考虑以下代码:
let pair = System.Tuple.Create (10, "foo") // val pair : int * string = (10, "foo")
let tuple = System.Tuple.Create <| (10, "foo") // val tuple : System.Tuple<int * string> = ((10, "foo"))
Run Code Online (Sandbox Code Playgroud)
(10, "foo")这两行之间的参数类型是否发生了某种变化?int * string和之间的确切区别是System.Tuple<int * string>什么?对于 2,至少后者具有null值(这就是这个问题的产生方式)。还有其他区别吗?
Yourtuple是一个包含一 (1) 个元素的元组,即 tuple 10,"foo"。它相当于
System.Tuple.Create(System.Tuple.Create(10, "foo"))
Run Code Online (Sandbox Code Playgroud)
pair另一方面,您的元组是两个元素 10 和“foo”。
所以pair有类型System.Tuple<int,string>(与 相同int * string),但元组有类型System.Tuple<System.Tuple<int,string>>(与System.Tuple<int * string>)
有两种不同的重载Tuple.Create:
Tuple.Create<'T1>(item1: 'T1)
Tuple.Create<'T1, 'T2>(item1: 'T1, item2: 'T2)
Run Code Online (Sandbox Code Playgroud)
在第一种情况下,您只需调用带有两个参数的方法。所以Tuple.Create显然选择了第二个过载。没有惊喜。
但是通过管道,您首先要创建一个元组实例。然后将其传递给Tuple.Create方法。这就是第二个例子中发生的事情
let intermediate : Tuple<int, string> = (10, "foo")
let tuple = Tuple.Create(intermediate)
Run Code Online (Sandbox Code Playgroud)
使用单个参数,Tuple.Create将选择第一个重载。
注意:星型是在 F# 中编写元组类型名称的一种方式。所以Tuple<int, string, bool>会(int * string * bool)。这是同一件事。