我有一些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"
我创建了一个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
}
我删除了关键字return
,因为我听说在scala中不需要它,但是显然,在这种情况下我无法删除它。如果不删除关键字return
,我将得到正确的结果。
为什么不能在这种情况下将其删除?还有其他在Scala中使用保护子句的方法吗?还是有其他原因导致意外输出?
答案 0 :(得分:5)
关键是要在Scala中理解,否则表达式只是-表达式,而不是控件结构。因此
if (x == 5) "equal to 5"
不代表
“如果x等于5,则返回5”,
相反,它意味着类似
“如果x等于5,则将该表达式求值为5,否则求值为未知值。”
实际上我们可以写
val v: Any = if (x == 5) "equal to 5"
请注意v
的类型是Any
,因为我们没有提供表达式的else
部分,所以最好的编译器可以做的就是推断Any
类型。提供我们拥有的else子句
val v: String = if (x == 5) "equal to 5" else "not equal to 5"
现在我们可以根据需要将v
键入String
了。现在在Scala中,如果我们将一个表达式作为 last 表达式放置在块中,则它将成为函数的返回值。因此
def temp(x: Int): String = {
if (x == 5)
"equal to 5"
"not equal to 5"
}
等同于
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
}
我们看到temp
的地方总是返回v2
。相反,我们应该简单地写
def temp(x: Int): String =
if (x == 5) "equal to 5" else "not equal to 5"
我们可以说if-else表达式只有在块中的最后一个表达式时才充当传统的控制结构。
更正式的说法是在conditional expression if (?1) ?2 else ?3
条件表达式的类型是?2
和?3
if (?1) ?2
的评估就像是if (?1) ?2 else ()
。
其中()
的值具有Unit
类型,其解释为here。