这个例子来自Beginning Scala,但它对我来说并没有得到足够的解释.
val f: Int => String = x => "Dude: "+x
Run Code Online (Sandbox Code Playgroud)
我真的有两个问题:
1)第一个示例是否与下面的代码相同:
val f = (x:Int) => "Dude: "+x
Run Code Online (Sandbox Code Playgroud)
2)如果是这样,有人可以详细说明,并稍微剖析第一个例子.String = x部分抛弃了我.我不确定如何阅读该声明
他们是一样的.您正在以两种不同的方式为您进行scala的类型推断.
在val f: Int => String = x => "Dude: "+x=符号之前的部分是你明确声明f类型的地方Int => String(即你说f是一个接受Int类型的输入并返回一个String的函数)在=的右边你指的是一个值到F.值(根据您的声明)必须是一个接受Int并返回String的函数.事实上,你说f等于x => "Dude: "+x.scala编译器的类型推断在这里工作,因为它理解x必须是一个Int,因为你已经将f声明为从Int到String的函数.
在val f = (x:Int) => "Dude: "+x你让scala的类型推断通过查看你赋给它的值来"猜测"f的类型.这个值(在=的右侧)是一个函数,它接受一个Int(因为你明确地说x:Int)并返回一个String(因为你将x添加到"Dude:",这是一个字符串,所以字符串的结果+ x必须是一个字符串本身).
注意:如果您在REPL中尝试两个版本,您会注意到在一种情况下,您将f定义为(Int)=> String,在另一种情况下,(Int)=> java.lang.String它们是(从scala 2.8.1开始,同样的事情:scala的字符串定义(在Predef.scala中)很简单 type String = java.lang.String.这可能是针对.NET框架的scala版本(其中String可能是.NET的System.String的别名),因此您可以始终在scala程序中编写String.
好的,我们走了:
line 1: val f: Int => String
Run Code Online (Sandbox Code Playgroud)
读取为声明为具有签名的值的函数,该签名将第一个输入值从类型映射到类型Int的输出值String.
line 1: ... = x => "Dude: " + x
Run Code Online (Sandbox Code Playgroud)
使用lambda(或函数文字)读取函数定义,该函数使用一个名为x的参数将其附加到字符串"Dude: "并返回它.此定义分配给该值f.由于f声明了值Int => String,x因此Int在编译器推断其类型时将采用该类型.在Scala中,函数体的最后一个表达式是return语句,String在这种情况下恰好也适用于我们的声明.此外,在Java和Scala中,运算符+过载.当您尝试将a添加String到a时Int,结果将是字符串值和整数的字符串连接.
现在看看这个:
line: 2 val f = (x:Int) => "Dude: " + x
Run Code Online (Sandbox Code Playgroud)
这一次,f没有用类型声明,它的类型是从它的定义推断出来的(x:Int) => "Dude: " + x,它是一个函数文字,它接受一个名为xtype 的参数Int并返回一个String.应该清楚的是,这两个版本现在是等价的.
现在作为练习,尝试编写一些使用该关键字的版本def.完成后,f()在REPL中键入所有内容并观察其签名.到那时应该很清楚.
| 归档时间: |
|
| 查看次数: |
1434 次 |
| 最近记录: |