本文介绍了`=>的类型是什么?在Scala中使用String`吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在scala中,有一些按名字呼叫的参数:

In scala, there is some call-by-name parameters:

def hello(who: => String) = println("hello, " + who)

参数who的类型是什么?

它将scala REPL上的功能显示为:

It shows the function on scala REPL as:

hello: (who: => String)Unit

类型是否仍为=> String?有什么名字吗?还是一些描述类型的文档?

Is the type still => String? Is there any name for it? Or some documentation to describe the type?

(阅读第3.3.1节(MethodTypes)的规范时)

(When reading the spec of §3.3.1 (MethodTypes))

方法类型是方法的类型,例如我定义了方法hello:

Method type is the type of a method, say I defined a method hello:

def hello: String = "abc"

它的类型可以写为:=> String,对吗?尽管您可以看到REPL响应是:

The type of the it can be written as: => String, right? Although you can see the REPL response is:

scala> def hello:String = "abc"
hello: String

如果我定义了一个带有参数的方法:

If I define a method which has parameters:

def goodname(name: String): String = name + "!"

该方法的类型是什么?它应该与String => String类似,但不相似.因为它是方法类型,而String => String是函数类型.

What's the type of the method? It should be similar to String => String, but not. Because it's a method type, and String => String is a function type.

(阅读第3.3.1节(MethodTypes)的规范时)

(When reading the spec of §3.3.1 (MethodTypes))

我可以这样理解:

def goodname(name: String): String = name + "!"
def print(f: String => String) = println(f("abc"))
print(goodname)

当我调用print(goodname)时,goodname的类型将转换为函数类型String => String,对吧?

When I call print(goodname), the type of goodname will be converted to the function type String => String, right?

但是对于无参数方法:

def hello: String = "abc"

可以转换什么功能类型?我试过了:

What function type can it be converted? I tried:

def print(f: () => String) = println(f())

但是无法编译:

print(hello)

错误是:

您能给我一个可行的例子吗?

Could you give me an example that works?

(阅读第6.26.2节(MethodConversions)的规范时)

(When reading the spec of §6.26.2 (MethodConversions))

仅当类型不应用于自变量时,才会发生此 Evaluation 转换.因此,对于代码:

This Evaluation conversion is only happened when the type is not applied to argument. So, for code:

def myname:String = "abc"
def print(name: => String) = println(name)
print(myname)

我的问题是,当我呼叫print(myname)时,是否发生了转换(我的意思是Evaluation conversion)?我猜想,由于myname的类型仅为=> String,因此可以将其直接传递给print.

My question is, when I call print(myname), is there conversion(I mean Evaluation conversion) happened? I guess, since the type of myname is just => String, so it can be passed to print directly.

如果print方法已更改:

def myname:String = "abc"
def print(name: String) = println(name)
print(myname)

Evaluation conversion肯定发生了,对吗?(从=> StringString)

Here the Evaluation conversion is definitely happened, right?(From => String to String)

推荐答案

规范的4.6.1节:

因此,按名称调用参数的类型是(大约)() => T(或者,如果愿意,可以是Function0[T]).如果:javap接受按名字调用参数的方法,您将看到编译后的代码接受scala.Function0<java.lang.Object>类型的参数.

So the type of a call-by-name param is (approximately) () => T (or Function0[T] if you prefer). If you :javap a method that accepts a call-by-name parameter you will see that the compiled code accepts a param of the type scala.Function0<java.lang.Object>.

翻译:

def callByName[T](f: => T) = f

callByName { /* magic */
    1 + 1
/* ends here */ }

有效:

def callByName[T](f: Function0[T]) = f.apply()

callByName(new Function0[Int] {
  def apply() = { /* magic */
    1 + 1
  /* ends here */ }
})

关于近似值的疑问

您可能很想尝试将() => T传递给您的方法.尝试callByName(() => 12);为什么不编译? (提示,请考虑在呼叫站点进行扩展). (将鼠标悬停在以下空白处可以查看答案):

Doubts surrounding the approximation

You may be tempted to try passing a () => T to your method. Try callByName(() => 12); why does it not compile? (Hint, consider the expansion at the call site). (Hover on the following blank to see the answer):

=> T实际是什么

=> T实际上是方法类型,而不是对象.因此,之前发生的所有事情都是编译器所做工作的近似值,并且可以随时更改.引用自§3.3 :

What => T actually is

=> T is actually a method type, not an object. So everything that goes before is an approximation of what the compiler does and can change at any time. Quoting from §3.3:

那么方法类型是什么?引用自§3.3.1(方法类型):

So what are method types? Quoting from §3.3.1 (MethodTypes):

方法类型不作为值类型存在.如果将方法名称用作值,则其类型将隐式转换为相应的函数类型(§6.26).

Method types do not exist as types of values. If a method name is used as a value, its type is implicitly converted to a corresponding function type (§6.26).

§6.26.3(MethodConversions )状态:

评估.类型为=> T的无参数方法m总是通过评估绑定到m的表达式而转换为类型T.

Evaluation. A parameterless method m of type => T is always converted to type T by evaluating the expression to which m is bound.

所以类型=> T的正确翻译总是:

So the proper translation of the type => T is always:

def random$name$here: T

示例

这是一个可以玩的示例类:

Example

Here's an example class to play around with:

class TestParamless {
  def paramless: Int = 1
  def callByName(f: => Int) = f
  def example: Int = callByName(paramless)
}

尝试new TestParamless().example,也尝试:javap TestParamless(在scala REPL中).

Try new TestParamless().example and also, :javap TestParamless (in the scala REPL).

这篇关于`=&gt;的类型是什么?在Scala中使用String`吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-03 06:43