完成Scala的初学者,并试图找出现在的基础知识.
作为教程的一部分,我正在尝试创建一个返回整数列表中最大元素的函数.为了实现这一点,我(暂时)将以下代码组合在一起:
def max(xs: List[Int]): Int =
if (xs.isEmpty)
throw new java.util.NoSuchElementException
else
findMax(xs.head, xs.tail)
def findMax(a: Int, b: List[Int]) {
if (b.isEmpty) return a
if (a > b.head)
findMax(a, b.tail)
else
findMax(b.head, b.tail)
}
Run Code Online (Sandbox Code Playgroud)
但是,当我尝试编译它时,我得到第5行的类型错误.
[error] /scala/example/src/main/scala/example/Lists.scala:5: type mismatch;
[error] found : Unit
[error] required: Int
[error] findMax(xs.head, xs.tail)
Run Code Online (Sandbox Code Playgroud)
我不得不承认我对这个错误消息感到有点困惑,因为我不明白编译器是怎么认为我试图传递一个Unit类型给定逻辑以确保List在此行之前不为空.
任何人都可以帮助澄清这个问题吗?
Scala有两个用于定义函数的结构:
def doSomething(a: Int) { a + 3 }
Run Code Online (Sandbox Code Playgroud)
和
def doSomethingElse(b: Int) = { b + 3 }
Run Code Online (Sandbox Code Playgroud)
第一个被称为过程语法,并且不鼓励它,因为它导致糟糕的假设和令人困惑的代码.这两个函数之间的区别在于doSomething返回Unit,而doSomethingElse返回Int.如果你不包含=,你的函数将不会返回任何内容(换句话说,它返回Unit).
这个
def doSomething(a: Int) { a + 3 }
Run Code Online (Sandbox Code Playgroud)
相当于
def doSomething(a: Int): Unit = { a + 3 }
Run Code Online (Sandbox Code Playgroud)
你希望你的函数findMax返回一个Int,但是因为你离开了它=,Scala说它返回了Unit.这是编译错误的原因.你可以通过写作来解决这个问题
def findMax(a: Int, b: List[Int]) = {
Run Code Online (Sandbox Code Playgroud)
要么
def findMax(a: Int, b: List[Int]): Int = {
Run Code Online (Sandbox Code Playgroud)
通常,您不应该使用过程语法.=即使您最终将最终返回类型留给类型推断,也要始终使用.
应该注意的是,第一种方法实际上可能会导致编译器错误,因为您return在函数中使用了该错误.return需要显式调用的函数来指定它们在函数头中返回的类型.因为Scala是一种基于表达式的语言,所以每个语句都是一个表达式,因此返回一个值.您可以将您的findMax功能重写为不需要return如下:
def findMax(a: Int, b: List[Int]): Int = {
if (b.isEmpty)
a
else if (a > b.head)
findMax(a, b.tail)
else
findMax(b.head, b.tail)
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
496 次 |
| 最近记录: |