[scala] 스칼라로 반환

저는 초보자 스칼라 프로그래머이며 이상한 행동을 보았습니다.

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.isEmptycount == 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 표현식입니다. 따라서의 반환 유형은 fInt입니다. 정말 문자열을 반환하기를 원한다면 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을 사용하면 실제로 코드가 손상되거나 적어도 분명하지 않은 효과가있는 경우에 대한 예를 제공합니다.

이 시점에서 게시물의 본질을 인용하겠습니다. 가장 중요한 진술은 시작 부분에 있습니다. 이것을 포스터로 인쇄하여 벽에 붙이십시오 🙂

return키워드는 “선택”또는 “추정”아니다; 프로그램의 의미를 변경하므로 절대 사용해서는 안됩니다.

함수를 인라인 할 때 실제로 무언가를 깨뜨리는 한 가지 예를 제공합니다.

// 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.

때문에

return식은 검사시하는 방법의 호출자에게 현재 연산 복귀 포기 return표시한다.

이것은 링크 된 게시물에 제공된 예제 중 하나 일 뿐이며 이해하기 가장 쉽습니다. 더 많은 것이 있고 나는 당신이 거기에 가서 읽고 이해하기를 적극 권장합니다.

Java와 같은 명령형 언어에서 왔을 때 처음에는 이상하게 보일 수 있지만이 스타일에 익숙해지면 이해가 될 것입니다. 다른 인용문으로 마무리하겠습니다.

일찍 돌아오고 싶다고 생각하는 상황에 처해 있다면 계산을 정의한 방식을 다시 생각해야합니다.


답변

저는 Scala를 프로그래밍하지 않지만 암시 적 반환 (Ruby)이있는 다른 언어를 사용합니다. if (elem.isEmpty)블록 뒤에 코드가 있습니다. 코드 의 마지막 줄은 반환되는 것이므로 예상 한 것을 얻지 못하는 것입니다.

편집 : 함수를 작성하는 더 간단한 방법이 있습니다. isEmpty의 부울 값과 count를 사용하여 true 또는 false를 자동으로 반환합니다.

def balanceMain(elem: List[Char]): Boolean =
{
    elem.isEmpty && count == 0
}


답변

쓰지 마십시오 if해당하지 않고 문을 else. else조각에을 추가하면 truefalse실제로 함수의 마지막 표현임을 알 수 있습니다.

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....


답변

기본적으로 함수의 마지막 표현식이 반환됩니다. 귀하의 예에는 반환 값을 원하는 지점 뒤에 또 다른 표현식이 있습니다. 마지막 표현식 이전에 무엇이든 반환하려면을 사용해야 return합니다.

다음과 같이 예제를 수정하여 Boolean첫 번째 부분에서

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
  }
}


답변

조기 반품을위한 사용 사례 일치. 어딘가에 return을 쓰는 것을 잊은 부주의 한 실수를 방지하기 위해 모든 return 브랜치를 명시 적으로 선언해야합니다.


답변