我有一些python代码,我想将其转换为scala。
Python代码:
def temp(x):
if(x == 5):
return "equal to 5" //basically, this would be a guard clause in a real world example
// Maybe do some processing
return "not equal to 5"
print(temp(5)) //prints "equal to 5"
print(temp(6)) //prints "not equal to 5"
Run Code Online (Sandbox Code Playgroud)
我创建了一个scala工作表,并尝试逐行翻译它,但是结果不一样。
Scala代码:
object test {
def temp(x: Int): String = {
if (x == 5)
"equal to 5"
"not equal to 5"
} //> temp: (x: Int)String
temp(5) //> res0: String = not equal to 5
temp(6) //> res1: String = not equal to 5
}
Run Code Online (Sandbox Code Playgroud)
我删除了关键字,return
是因为我读到它在scala中不是必需的,但是显然,在这种情况下我无法删除它。如果不删除关键字,我将得到正确的结果return
。
为什么不能在这种情况下将其删除?还有其他在Scala中使用保护子句的方法吗?还是有其他原因导致意外输出?
关键是要在Scala中理解if-else 表达式仅仅是- 表达式,而不是控制结构。因此
if (x == 5) "equal to 5"
Run Code Online (Sandbox Code Playgroud)
并不意味着
“如果x等于5,则返回5”,
相反,它意味着类似
“如果x等于5,则将该表达式求值为5,否则求值为未知值。”
实际上我们可以写
val v: Any = if (x == 5) "equal to 5"
Run Code Online (Sandbox Code Playgroud)
请注意的类型v
是Any
,因为我们没有提供else
表达式的一部分,所以最好的编译器可以做的就是推断Any
类型。提供else子句
val v: String = if (x == 5) "equal to 5" else "not equal to 5"
Run Code Online (Sandbox Code Playgroud)
v
现在,我们可以String
根据需要很好地将其键入。现在在Scala中,如果我们将表达式作为块中的最后一个表达式,则它将成为函数的返回值。从而
def temp(x: Int): String = {
if (x == 5)
"equal to 5"
"not equal to 5"
}
Run Code Online (Sandbox Code Playgroud)
相当于
def temp(x: Int): String = {
val v1: Any = if (x == 5) "equal to 5"
// do nothing with v1
val v2: String = "not equal to 5"
return v2
}
Run Code Online (Sandbox Code Playgroud)
我们看到的地方temp
永远只会返回v2
。相反,我们应该简单地写
def temp(x: Int): String =
if (x == 5) "equal to 5" else "not equal to 5"
Run Code Online (Sandbox Code Playgroud)
我们可以说if-else表达式只有在块中的最后一个表达式时才充当传统的控制结构。
更正式地,在条件表达式中 if (1) 2 else 3
条件表达式的类型是和类型的最弱最小上限2
3
if (1) 2
评估为if (1) 2 else ()
。
其中()
value具有Unit
类型,在此进行说明。