有几次我看到像这样的Scala代码:
object Doer{
def doStuff(op: => Unit) {
op
}
}
Run Code Online (Sandbox Code Playgroud)
以这种方式调用:
Doer.doStuff{
println("Done")
}
Run Code Online (Sandbox Code Playgroud)
对我来说奇怪的是函数如何作为花括号之间的代码块传递给另一个函数.甚至没有括号通常标记参数列表的开头和结尾.
这个Scala语法/功能的名称是什么?在什么情况下我可以使用它?它在哪里记录?
可能重复:
Scala中的函数与方法Scala中
def foo = {}和def foo()= {}之间的区别是什么?
在scala我们可以定义
def foo():Unit = println ("hello")
Run Code Online (Sandbox Code Playgroud)
要么
def foo:Unit = println ("hello")
Run Code Online (Sandbox Code Playgroud)
我知道它们不一样但有什么区别,哪些应该在什么时候使用?
如果之前已经回答过,请指出我的链接.
在Scala中,有两种方法可以定义一个不带参数的方法
1 def a=println("hello")
2 def a()=println("hello")
Run Code Online (Sandbox Code Playgroud)
这两种方法完全相同,但(2)可以使用和不使用括号来调用.
在Scala中是否有任何特殊原因允许使用此功能.它会让我感到困惑,何时使用?
所以我正在学习Scala,我遇到了这个挑剔的问题......
如果我们有一个String并希望将其转换成一个Int,我在网上找到的所有例子都说:"这很简单!只需使用String.toInt!"
好的:
var x = readLine().toInt
Run Code Online (Sandbox Code Playgroud)
很简单.我假设toInt是一个功能String.但如果是这样的话,我应该可以toInt用括号打电话,对吧?来自Java,这对我来说更自然:
var x = readLine().toInt()
Run Code Online (Sandbox Code Playgroud)
可惜!Scala给了我以下错误:
[错误] /home/myhome/code/whatever/hello.scala:13:Int不带参数
[error] var x = readLine().toInt()
好奇.这个错误是什么意思?是toInt不是一个功能String?同样,为什么我可以两个都做:
var x = readLine().toLowerCase()
var y = readLine().toLowerCase
Run Code Online (Sandbox Code Playgroud)
没有任何问题?
编辑:重复的问题不解决toLowerCasevs toInt问题.
我的scala测试文件中有很多nullary方法(带0参数的方法).因此,而不是将它们写成:
def fooBar() = //
Run Code Online (Sandbox Code Playgroud)
我把它们写成:
def fooBar = //
Run Code Online (Sandbox Code Playgroud)
当我这样做时,我收到以下警告:
Warning:(22, 7) side-effecting nullary methods are discouraged: suggest defining as `def fooBar()` instead
Run Code Online (Sandbox Code Playgroud)
警告的含义是什么?我使用intelliJ作为我的IDE,并且在网上找不到这个警告.
编辑
而且,我忘了提及,当我使用括号时,警告不会出现.
考虑以下2个对象
object TestObj1 {
def testMethod = "Some text"
}
object TestObj2 {
def testMethod() = "Some text"
}
Run Code Online (Sandbox Code Playgroud)
如果我直接调用这些方法,他们就会按照我的期望行事
scala> TestObj1.testMethod
res1: String = Some text
scala> TestObj2.testMethod
res2: String = Some text
Run Code Online (Sandbox Code Playgroud)
但现在如果我们定义以下功能
def functionTakingFunction(callback: () => String) {
println("Call returns: " + callback())
}
Run Code Online (Sandbox Code Playgroud)
并尝试调用它,不接受没有()定义的方法.
scala> functionTakingFunction(TestObj1.testMethod)
<console>:10: error: type mismatch;
found : String
required: () => String
functionTakingFunction(TestObj1.testMethod)
^
scala> functionTakingFunction(TestObj2.testMethod)
Call returns: Some text
Run Code Online (Sandbox Code Playgroud)
我还注意到你不能使用括号调用TestObj1.testMethod,因为它已经是一个String.但是什么导致了这种行为?
我有一个编译错误,我不明白。
case class Point(x: Int, y: Int)
trait Rectangular {
def topLeft: Point
def bottomRight: Point
def left = topLeft().x //Compile error occurring here
def right = bottomRight.x
def width = right - left
// any many more concrete geometric methods.
}
Run Code Online (Sandbox Code Playgroud)
我在定义第三种方法的行上收到编译错误,说“Point 不带参数”。
但是我认为您可以调用一个不带参数的函数,无论是否带有(). AstopLeft只是一个没有参数且返回类型为Point.
不要用文字描述问题,而是让我向你展示一个Scala Interpreter会话,它展示了我想要做的事情.
scala> class A extends Parent{
| def name = "Alex"
| }
defined class A
scala> class B extends Parent{
| def name = "Bernardo"
| }
defined class B
scala> def addFamilyName[T <: Parent](fn:String, c:T{def name():String}) = c.name + " " + fn
addFamilyName: [T <: Parent](fn: String, c: T{def name(): String})java.lang.String
scala> addFamilyName( "Martins", new A())
<console>:11: error: type mismatch;
found : A
required: ?{def name(): String}
addFamilyName( "Martins", new A())
^
Run Code Online (Sandbox Code Playgroud)
所以基本上我想在参数中定义一个类型,它既是某个类型的子类,也包含一个带签名的方法 def name():String. …
scala ×8
function ×2
methods ×2
parentheses ×2
integer ×1
parameters ×1
string ×1
syntax ×1
traits ×1
types ×1