F#中的collection initializer语法是什么?在C#中,您可以编写如下内容:
new Dictionary<string, int>() {
{"One", 1},
{"two", 2}}
我如何在F#中做同样的事情?我想我可以推出自己的语法,但似乎应该有一个内置的或标准的。
答案 0 :(得分:69)
在F#中详细说明集合初始化,这里有几个例子:
只读字典
dict [ (1, "a"); (2, "b"); (3, "c") ]
seq(IEnumerable&lt; T&gt;)
seq { 0 .. 99 }
<强>列表强>
[1; 2; 3; 4; 5]
设置强>
set [1; 2; 3; 4; 5]
<强>阵列强>
[| 1; 2; 3; 4; 5 |]
答案 1 :(得分:26)
正如Jared所说,对于任意集合,没有内置的支持。但是,C#代码只是Add
方法调用的语法糖,因此您可以将其转换为:
let coll = MyCollectionType()
["One", 1; "Two", 2] |> Seq.iter coll.Add
如果您想获得幻想,可以创建inline
定义以进一步简化:
let inline initCollection s =
let coll = new ^t()
Seq.iter (fun (k,v) -> (^t : (member Add : 'a * 'b -> unit) coll, k, v)) s
coll
let d:System.Collections.Generic.Dictionary<_,_> = initCollection ["One",1; "Two",2]
答案 2 :(得分:11)
我不相信F#有一个明确的集合初始化语法。但是,初始化F#集合通常非常容易。例如
let map = [ ("One", 1); ("Two", 2) ] |> Map.ofSeq
进入BCL系列通常会有点困难,因为他们并不总是拥有方便的转换功能。 Dictionary<TKey, TValue>
可以工作,因为你可以使用LINQ方法
let map =
let list = [ ("One", 1); ("Two", 2) ]
System.Linq.Enumerable.ToDictionary(list, fst, snd)
答案 3 :(得分:3)
你可以使用相同的:
open System.Collections.Generic
Dictionary<int, string>(dict [ (1, "a"); (2, "b"); (3, "c") ])
干杯。
答案 4 :(得分:2)
缺少集合初始化程序对于一些以XAML为中心的API(如Workflow 4.0,它依赖于集合初始化程序而不是ctors)来说很烦人,例如
new Sequence { Activities = { WriteLine { Text = "In the sequence!" } } };
在这种情况下,命令式.Add()很尴尬,因为值是概念声明的,即使它在技术上是可变的/命令式的。但是,没有公共基类用于声明活动子项的所有活动的集合:“活动”成员是模式而不是接口,因此您不能只编写正常的帮助函数这会将孩子添加到任何活动中。幸运的是,F#成员限制得救了。
为了写这个:
Sequence() |> add [Sequence(DisplayName="InnerSeq"); WriteLine(Text = InArgument<_>("In the sequence!"))]
首先需要定义一个名为“add”的内联辅助函数:
let inline add (children: Activity seq) =
let inline doAdd (activity: ^Activity) : ^Activity when ^Activity : (member get_Activities : unit -> Activity Collection) =
let collection = (^Activity : (member get_Activities : unit -> Activity Collection) (activity))
for child in children do
collection.Add(child)
activity
doAdd
这仍然不如C#语法好,但至少它仍然是声明性的。恕我直言,这不是F#的错误,而是以集合初始化程序为中心的API,但至少F#允许解决方法。
答案 5 :(得分:0)
鉴于C#集合初始化器语法是用于调用.Add
的语法糖并且暗示了一个可变集合 - 我不确定你会在F#中看到任何这样的语法。根据JaredPar的回答,它可以一次性初始化,也可以手动完成。