def hello(who: => String) = println("hello, " + who)
参数 who
的类型是什么?
在 Scala REPL 中,它显示为以下函数:
hello: (who: => String)Unit
这种类型仍然是=> String
吗?它有任何名称吗?或者有一些文档来描述这种类型吗?
answer引发的进一步问题
问题1
(阅读§3.3.1规范(方法类型)时)
方法类型是方法的类型,比如我定义了一个方法hello
:
def hello: String = "abc"
这个类型可以写成:
=> 字符串
,对吧?虽然你可以看到REPL的响应是:scala> def hello:String = "abc"
hello: String
如果我定义了一个带有参数的方法:
def goodname(name: String): String = name + "!"
这个方法的类型是什么?它应该类似于 String => String
,但不完全相同。因为它是一个方法类型,而 String => String
是一个函数类型。
问题2
(阅读 §3.3.1(方法类型)规范时)
我可以理解为:
def goodname(name: String): String = name + "!"
def print(f: String => String) = println(f("abc"))
print(goodname)
当我调用
print(goodname)
时,goodname
的类型会转换为函数类型String => String
,对吗?但是对于无参数方法:
def hello: String = "abc"
它可以转换为哪种函数类型?我尝试了:
def print(f: () => String) = println(f())
但这无法编译:
print(hello)
错误信息为:
错误:类型不匹配; 找到的是:String 需要的是:() => String
你能给我一个可行的例子吗?
问题3
(当阅读§6.26.2规范(方法转换)时)
只有在参数未应用类型时才会发生评估转换。因此,对于代码:
def myname:String = "abc"
def print(name: => String) = println(name)
print(myname)
我的问题是,当我调用
print(myname)
时,是否发生了转换(我指的是评估转换
)?我猜想,由于myname
的类型只是=> String
,因此可以直接传递给print
。如果
print
方法已更改:def myname:String = "abc"
def print(name: String) = println(name)
print(myname)
这里肯定发生了“评估转换”,对吗?(从=> String
转换为 String
)
()=>String
,因为hello(() => "Freewind")
无法编译。 - Freewindmyname
的类型是什么? - Sean VieiraFunctionN
中包装对它们的调用,将它们转换为值,其中apply
方法调用底层方法。因此,当您将goodname
传递给print
时,您正在向print
传递Function1 [String,String]
的实例,该实例调用goodname
:print(new Function1[String, String] { def apply(v: String) = goodname(v) })
。 - Sean VieiraFunction0[T]
。你遇到的问题是因为编译器正在调用hello
(因为这样的方法“每次引用无参数方法名称时都会重新评估”)。你必须明确告诉编译器使用_
来推迟评估,而不是print(hello)
,应该是print(hello _)
。 - Sean Vieiraprintln(name)
中引用name
时,会发生评估转换。在您的第二个示例中,是的,您是正确的,myname
在调用站点进行评估。print(myname)
是print(myname())
,即print("abc")
。 - Sean Vieira