Ответ 1
Чтобы немного раскрыть правильный ответ Джона Палмера, здесь F # Интерактивный сеанс, который иллюстрирует, как 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"
So List<int>
с верхним регистром L будет типом списка F # (неизменный связанный список с указателем головы, который имеет доступ к O (1) и доступ к нему, но O (N) хвост и добавление), если вы не открыли пространство имен System.Collections.Generic
. Но если у вас есть, то вдруг List<int>
переходит к классу .Net System.Collections.Generic.List<T>
, который является изменяемой структурой данных с O (1) поисками в любом месте, аффицирует O (1), но O (N) добавляет. Поэтому действительно важно, какой из них вы используете.
Чтобы быть в безопасности, если вы намереваетесь использовать структуру списка F #, я бы написал ее как int list
(мои предпочтения, так как они читаются как английский) или List<int>
(которые некоторые предпочитают с тех пор читается как С#). Ни один из них внезапно не приобретет другой смысл при открытии пространства имен .Net; они будут продолжать ссылаться на структуру списка F #. И избегайте использования List<int>
для ссылки на списки F #; используйте это, только когда вы открыли пространство имен System.Collections.Generic
, и вы намерены получить экземпляр .Net System.Collections.Generic.List<T>
. Наконец, обратите внимание, что в F # System.Collections.Generic.List<T>
имеет псевдоним типа, не открывая пространство имен System.Collections.Generic
. По умолчанию без открытия каких-либо пространств имен вы можете получить доступ к этому типу под именем ResizeArray<T>
.
Резюме:
Безопасные имена типов:
-
int list
иList<int>
(всегда ссылайтесь на тип списка односвязных F #) -
ResizeArray<int>
(всегда относится к типу С#System.Collections.Generic.List<T>
)
Небезопасные имена типов, поскольку их значение изменяется в зависимости от того, какое пространство имен вы открыли:
-
List<int>
(сначала ссылается на тип списка с односвязным именем F #, но при изменении пространства именSystem.Collections.Generic
изменяется значение типа С#). Как правило, не используйте это имя типа; если вы хотите этот тип в F #, используйтеResizeArray<int>
вместо этого.