2016-12-12 13 views
11

क्या List<int> और int list के बीच कोई अंतर है? उदाहरण के लिए, जब मैं एक समारोह लिखनेसूची <int> बनाम int सूची

let somefn a : int list = a 

और

let somefn2 a : List<int> = a 

दिए गए मान प्रकार अंकन शैली के साथ भिन्न होते हैं, और यहां तक ​​कि सांत्वना उत्पादन में, जब मैं उन कार्यों को लागू, यह पता चलता दो साफ़ तौर पर उल्लेख किया प्रकार

val it : int list = ... 

और

val it : List<int> = ... 

हालांकि, तर्क और विचार समान प्रतीत होता है, इंटरप्रेटर/कंपाइलर उन दो प्रकारों को एक अलग तरीके से व्याख्या करता है।

क्या कोई अंतर है?

उत्तर

7

कोई अंतर नहीं है, एक प्रकार उपनाम है।

एक मामले में, जहां

open System.Collections.Generic 

जो अपनी ही सूची प्रकार

16

जॉन पामर के सही जवाब पर थोड़ा विस्तार करने के लिए है चलाने के नीचे छोड़कर, यहां एक एफ # इंटरएक्टिव सत्र कि दिखाता है कि कैसे int list और List<int> है समानार्थक हैं, ठीक उसी समय तक जब वे नहीं हैं। और ध्यान दें कि वहाँ भी है list<int> और अतिरिक्त भ्रम के लिए ResizeArray<int>:

F# Interactive for F# 4.0 (Open Source Edition) 
Freely distributed under the Apache 2.0 Open Source License 

For help type #help;; 

> typeof<list<int>>.Namespace ;; 
val it : string = "Microsoft.FSharp.Collections" 
> typeof<list<int>>.Name ;;  
val it : string = "FSharpList`1" 
> typeof<List<int>>.Namespace ;; 
val it : string = "Microsoft.FSharp.Collections" 
> typeof<List<int>>.Name ;;  
val it : string = "FSharpList`1" 
> typeof<int list>.Namespace ;; 
val it : string = "Microsoft.FSharp.Collections" 
> typeof<int list>.Name ;;  
val it : string = "FSharpList`1" 
> typeof<ResizeArray<int>>.Namespace ;; 
val it : string = "System.Collections.Generic" 
> typeof<ResizeArray<int>>.Name ;;  
val it : string = "List`1" 
- 
- printfn "Now we'll open System.Collections.Generic. Watch what happens." 
- ;; 
Now we'll open System.Collections.Generic. Watch what happens. 
val it : unit =() 
> open System.Collections.Generic ;; 
> typeof<list<int>>.Namespace ;; 
val it : string = "Microsoft.FSharp.Collections" 
> typeof<list<int>>.Name ;; 
val it : string = "FSharpList`1" 
> typeof<List<int>>.Namespace ;; 
val it : string = "System.Collections.Generic" 
> typeof<List<int>>.Name ;;  
val it : string = "List`1" 
> typeof<int list>.Namespace ;; 
val it : string = "Microsoft.FSharp.Collections" 
> typeof<int list>.Name ;; 
val it : string = "FSharpList`1" 
> typeof<ResizeArray<int>>.Namespace ;; 
val it : string = "System.Collections.Generic" 
> typeof<ResizeArray<int>>.Name ;;  
val it : string = "List`1" 

तो List<int> एक अपरकेस एल एफ # सूची प्रकार (एक सिर सूचक के साथ एक अपरिवर्तनीय लिंक्ड सूची है, जो हे (1) सिर का उपयोग और है हो जाएगा के साथ पूर्ववत, लेकिन ओ (एन) पूंछ का उपयोग और संलग्न) यदि आपने System.Collections.Generic नामस्थान खोला नहीं है। लेकिन यदि आप में हैं, तो अचानक List<int> .NET System.Collections.Generic.List<T> क्लास का हल करता है, जो म्यूटेबल डेटा संरचना को ओ (1) लुकअप के साथ कहीं भी, एमोरेटेड ओ (1) संलग्न करता है, लेकिन ओ (एन) प्रीपेन्ड करता है। तो यह वास्तव में मामलों है जिसका आप उपयोग कर रहे हैं।

सुरक्षित पक्ष पर रहने के लिए, यदि आप एफ # सूची संरचना का उपयोग करना चाहते हैं, तो मैं इसे int list (मेरी पसंद से अंग्रेजी की तरह पढ़ता है) या list<int> (जो कुछ लोग पसंद करते हैं क्योंकि यह सी #)। जब आप नेट नामस्थान खोलते हैं तो उनमें से कोई भी अचानक एक अलग अर्थ प्राप्त नहीं करेगा; वे एफ # सूची संरचना का उल्लेख करना जारी रखेंगे। और F # सूचियों को संदर्भित करने के लिए List<int> का उपयोग करने से बचें; केवल तब उपयोग करें जब आपने System.Collections.Generic नामस्थान खोला है और आप .NET System.Collections.Generic.List<T> उदाहरण प्राप्त करना चाहते हैं। अंत में, ध्यान दें कि F #, System.Collections.Generic.List<T> में System.Collections.Generic नामस्थान खोलने के बिना एक प्रकार का उपनाम उपलब्ध है। डिफ़ॉल्ट रूप से, किसी भी नामस्थान को खोलने की आवश्यकता के बिना, आप इस प्रकार को ResizeArray<T> नाम से एक्सेस कर सकते हैं।

सारांश:

सुरक्षित प्रकार के नाम:

  • int list और list<int> (हमेशा एफ # अकेले लिंक्ड सूची प्रकार का उल्लेख)
  • ResizeArray<int> (हमेशा सी # System.Collections.Generic.List<T> प्रकार को संदर्भित करता है)

असुरक्षित प्रकार के नाम क्योंकि उनके अर्थ क्या नाम स्थान आपके द्वारा खोले गए के आधार पर परिवर्तन:

  • List<int> (करने के लिए पहली बार में अकेले लिंक्ड सूची प्रकार एफ # संदर्भित करता है, लेकिन परिवर्तन सी # प्रकार के, अर्थात यदि आप खोलने System.Collections.Generic नामस्थान)। एक सामान्य नियम के रूप में, इस प्रकार के नाम का उपयोग न करें; यदि आप इस प्रकार को एफ # में चाहते हैं, तो इसके बजाय ResizeArray<int> का उपयोग करें।
+4

शायद यह कहने के लिए एक हिस्सा जोड़ें कि 'System.Collections.Generic.List ' और साथ ही एक उपनाम 'ResizeArray'' और इसलिए उस विशिष्ट चीज़ के लिए किसी को नामस्थान – Sehnsucht

+0

@Sehnsucht खोलने की आवश्यकता नहीं है - अच्छा विचार! किया हुआ। – rmunn

3
  • आम तौर पर, एक पैरामीटर के साथ सामान्य प्रकार के लिए, TypeParameter GenericTypeGenericType<TypeParameter> के बराबर है।

  • FSharp.Core में घोषित एफ # अपरिवर्तनीय सूची प्रकार डिफ़ॉल्ट रूप से दो नामों के दायरे में है: List और list। इसमें एक प्रकार का पैरामीटर है, इसलिए int list, list<int>, int List, और List<int> समकक्ष हैं।

  • System.Collections.Generic में एक अलग List<'T> प्रकार है, जिसमें F # में अधिक उपयुक्त उर्फ ​​ResizeArray है। यदि आप System.Collections.Generic खोलते हैं, List इस उत्परिवर्तनीय, सरणी-रैपिंग प्रकार को संदर्भित करता है।

भ्रम से बचने के लिए, यह प्रथागत है एक पूंजी L साथ List का उपयोग नहीं करने के लिए एफ # में एक प्रकार का उल्लेख करने के। इसके बजाय, list लोअरकेस l के साथ एफपी-उत्पत्ति, अपरिवर्तनीय, एकल-लिंक्ड सूचियों के लिए उपयोग किया जाता है, जबकि ResizeArray का उपयोग ओओ-शैली परिवर्तनीय संग्रह को संदर्भित करने के लिए किया जाता है। अधिकांश लोग int list बनाम ResizeArray<int> बनाम विभिन्न शैलियों से चिपके रहते हैं और अन्य संयोजनों से बचते हैं।

प्रकार की जानकारी के लिए, आईडीई और इसी तरह के कभी-कभी उन्हें घोषित किए जाने के तरीके को प्रदर्शित करने का प्रयास करते हैं, क्योंकि एक ही प्रकार के संदर्भ में अक्सर कई तरीके होते हैं। यह व्यवहार में एक अंतर नहीं दर्शाता है।

संबंधित मुद्दे