类定义:
val
或var
可以从类参数中省略,这会将参数设为私有。
添加var或val将使其公开(即,生成方法访问器和变异器)。
{}
如果该类没有主体,则可以省略,即
class EmptyClass
类实例化:
如果通用参数可以由编译器推断,则可以省略。但是请注意,如果您的类型不匹配,则总是会推断出type参数以使其匹配。因此,如果不指定类型,则可能无法获得期望的结果-即
class D[T](val x:T, val y:T);
这会给你一个类型错误(发现整数,预期的字符串)
var zz = new D[String]("Hi1", 1) // type error
而这很好用:
var z = new D("Hi1", 1)
== D{def x: Any; def y: Any}
因为类型参数T被推断为两者中最不常见的超类型-Any。
函数定义:
=
如果函数返回Unit(无),则可以将其删除。
{}
如果函数是单个语句,则可以删除函数主体,但前提是该语句返回一个值(您需要使用=
符号),即,
def returnAString = "Hi!"
但这不起作用:
def returnAString "Hi!" // Compile error - '=' expected but string literal found."
如果可以推断出函数的返回类型,则可以忽略它(递归方法必须指定其返回类型)。
()
如果函数不接受任何参数,则可以将其删除,也就是说,
def endOfString {
return "myDog".substring(2,1)
}
按照惯例,它保留给没有副作用的方法-稍后再介绍。
()
实际上,在定义“ 按名称传递”参数时实际上并没有删除它,但实际上是一个语义上完全不同的符号,即,
def myOp(passByNameString: => String)
说myOp接受了一个pass-by-name参数,该参数导致一个String(即它可以是一个返回字符串的代码块)与函数参数相对,
def myOp(functionParam: () => String)
这表示myOp
需要一个具有零参数的函数并返回一个String。
(请记住,传递名称的参数会编译为函数;这只会使语法更好。)
()
如果函数仅接受一个参数,则可以将其放在函数参数定义中,例如:
def myOp2(passByNameString:(Int) => String) { .. } // - You can drop the ()
def myOp2(passByNameString:Int => String) { .. }
但是,如果需要多个参数,则必须包含():
def myOp2(passByNameString:(Int, String) => String) { .. }
声明:
.
可以删除以使用运算符表示法,该运算符只能用于中缀运算符(采用参数的方法的运算符)。有关更多信息,请参见Daniel的答案。
因为此表示法是按惯例保留给没有副作用的方法(如List#tail)使用的(即,调用没有副作用的函数意味着该函数除返回值外没有任何可观察的效果)。
调用带有函数的函数时,不能从内部函数定义中省略(),例如:
def myOp3(paramFunc0:() => String) {
println(paramFunc0)
}
myOp3(() => "myop3") // Works
myOp3(=> "myop3") // Doesn't work
当调用带有by-name参数的函数时,不能将参数指定为无参数的匿名函数。例如,给定:
def myOp2(passByNameString:Int => String) {
println(passByNameString)
}
您必须将其称为:
myOp("myop3")
要么
myOp({
val source = sourceProvider.source
val p = myObject.findNameFromSource(source)
p
})
但不是:
myOp(() => "myop3") // Doesn't work
IMO,过度使用丢弃返回类型对于重新使用代码可能有害。只看一下规范,这是由于代码中缺少显式信息而导致降低可读性的一个好例子。实际上可以弄清楚变量类型是什么的间接级别数可以说是胡说八道。希望有更好的工具可以避免这个问题,并使我们的代码简洁。
(好的,为了寻求一个更完整,简洁的答案(如果我错过了任何内容,或者遇到了一些错误/不正确的地方,请发表评论),我已经在答案的开头添加了。请注意,这不是一种语言规范,因此我并没有试图使其在学术上完全正确-就像参考卡一样。)