스칼라로 반환
저는 초보자 스칼라 프로그래머이며 이상한 행동을 보았습니다.
def balanceMain(elem: List[Char]): Boolean =
{
if (elem.isEmpty)
if (count == 0)
true;
else false;
if (elem.head == '(')
balanceMain(elem.tail, open, count + 1);....
위의 기본적으로 true if elem.isEmpty
및 count == 0
. 그렇지 않으면 false를 반환하고 싶습니다.
이제 위에서 나는 스칼라에 return 문을 추가 할 필요가 없다는 것을 읽었습니다. 그래서 return
위에서 생략했습니다 . 그러나 부울을 반환하지 않습니다. return 문을 return true
. 완벽하게 작동합니다. 왜 그래야만하지?
또한 스칼라에서 return 문을 사용하는 것이 왜 나쁜 습관으로 간주됩니까?
return
키워드를 생략하는 것만 큼 간단하지 않습니다 . Scala에서 없으면 return
마지막 표현식이 반환 값으로 사용됩니다. 따라서 마지막 표현식이 반환하려는 것이라면 return
키워드를 생략 할 수 있습니다 . 그러나 반환하려는 것이 마지막 표현식 이 아닌 경우 Scala 는 반환하려는 것을 알지 못합니다 .
예 :
def f() = {
if (something)
"A"
else
"B"
}
여기서 함수의 마지막 표현식은 f
문자열로 평가되는 if / else 표현식입니다. 명시 적으로 return
표시 되지 않았기 때문에 Scala는이 if / else 표현식의 결과 인 문자열을 반환하기를 원한다고 추론합니다.
이제 if / else 표현식 뒤에 무언가를 추가 하면 :
def f() = {
if (something)
"A"
else
"B"
if (somethingElse)
1
else
2
}
이제 마지막 표현식은 Int로 평가되는 if / else 표현식입니다. 따라서의 반환 유형은 f
Int입니다. 우리가 정말로 String을 반환하기를 원했다면, Scala는 그것이 우리가 의도 한 것이 무엇인지 알지 못 하기 때문에 문제가됩니다 . 따라서 문자열을 변수에 저장하고 두 번째 if / else 표현식 다음에 반환하거나 순서를 변경하여 문자열 부분이 마지막에 발생하도록 수정해야합니다.
마지막으로 다음 return
과 같이 중첩 된 if-else 표현식으로도 키워드를 피할 수 있습니다.
def f() = {
if(somethingFirst) {
if (something) // Last expression of `if` returns a String
"A"
else
"B"
}
else {
if (somethingElse)
1
else
2
"C" // Last expression of `else` returns a String
}
}
이 주제는 지금까지 답변에서 설명한 것처럼 실제로 조금 더 복잡합니다. Rob Norris 의이 블로그 게시물은 이 를 더 자세히 설명하고 return을 사용하면 실제로 코드가 손상되거나 적어도 분명하지 않은 효과가있는 경우에 대한 예를 제공합니다.
At this point let me just quote the essence of the post. The most important statement is right in the beginning. Print this as a poster and put it to your wall :-)
The
return
keyword is not “optional” or “inferred”; it changes the meaning of your program, and you should never use it.
It gives one example, where it actually breaks something, when you inline a function
// Inline add and addR
def sum(ns: Int*): Int = ns.foldLeft(0)((n, m) => n + m) // inlined add
scala> sum(33, 42, 99)
res2: Int = 174 // alright
def sumR(ns: Int*): Int = ns.foldLeft(0)((n, m) => return n + m) // inlined addR
scala> sumR(33, 42, 99)
res3: Int = 33 // um.
because
A
return
expression, when evaluated, abandons the current computation and returns to the caller of the method in whichreturn
appears.
This is only one of the examples given in the linked post and it's the easiest to understand. There're more and I highly encourage you, to go there, read and understand.
When you come from imperative languages like Java, this might seem odd at first, but once you get used to this style it will make sense. Let me close with another quote:
If you find yourself in a situation where you think you want to return early, you need to re-think the way you have defined your computation.
I don't program Scala, but I use another language with implicit returns (Ruby). You have code after your if (elem.isEmpty)
block -- the last line of code is what's returned, which is why you're not getting what you're expecting.
EDIT: Here's a simpler way to write your function too. Just use the boolean value of isEmpty and count to return true or false automatically:
def balanceMain(elem: List[Char]): Boolean =
{
elem.isEmpty && count == 0
}
Don't write if
statements without a corresponding else
. Once you add the else
to your fragment you'll see that your true
and false
are in fact the last expressions of the function.
def balanceMain(elem: List[Char]): Boolean =
{
if (elem.isEmpty)
if (count == 0)
true
else
false
else
if (elem.head == '(')
balanceMain(elem.tail, open, count + 1)
else....
By default the last expression of a function will be returned. In your example there is another expression after the point, where you want your return value. If you want to return anything prior to your last expression, you still have to use return
.
You could modify your example like this, to return a Boolean
from the first part
def balanceMain(elem: List[Char]): Boolean = {
if (elem.isEmpty) {
// == is a Boolean resulting function as well, so your can write it this way
count == 0
} else {
// keep the rest in this block, the last value will be returned as well
if (elem.head == "(") {
balanceMain(elem.tail, open, count + 1)
}
// some more statements
...
// just don't forget your Boolean in the end
someBoolExpression
}
}
Use case match for early return purpose. It will force you to declare all return branches explicitly, preventing the careless mistake of forgetting to write return somewhere.
참고URL : https://stackoverflow.com/questions/12560463/return-in-scala
'Program Tip' 카테고리의 다른 글
XML로 정의 된 기존 규칙을 프로그래밍 방식으로 제거하려면 어떻게합니까? (0) | 2020.11.07 |
---|---|
setInterval 타이머를 어떻게 재설정합니까? (0) | 2020.11.07 |
node-inspector로 node.js 디버깅 (0) | 2020.11.07 |
Angular의 한 요소에 여러 템플릿 바인딩을 적용하는 방법 (0) | 2020.11.07 |
Ruby on Rails의 모델 내에서 current_user에 액세스 (0) | 2020.11.07 |