2014-11-14 3 views
3

필자는 최근에 스칼라 삼항 연산자의 구현을 특히 많이 활성화/비활성화 된 이미지를 토글하는 데 사용했습니다. 그러나 일반적으로 찾은 코드 스 니펫을 이해할 수는 있지만 혼란 스럽습니다. 나는 또한 나의 필요에 더 잘 적응할 수 있도록 약간 수정하려고한다. 내가 다른 블록 등 자세한 경우 연산자 - 흉내 문법을 좋아해요.이 삼항 연산자의 구현은 어떻게 작동합니까?

implicit def BooleanBool(b: Boolean): Bool = Bool(b) 

case class Bool(b: Boolean) { 
    def ?[X](t: => X) = new { 
    def |(f: => X) = if (b) t else f 
    } 
} 

그래서 나는 암시 적으로 Bool 개체를 생성 이해하십니까? 함수로서. 이 함수는 X 유형의 값을 반환해야합니다. 나머지는 이해하기 위해 고생합니다. Heres는

내 질문 :

  1. 중첩 된 함수 작업을 수행하는 방법? | 기능.
  2. 코드가 실제로 처리하는 순서는 무엇입니까?
  3. 다른 절이 없도록 옵션을 변경하려면 어떻게해야합니까? 예. SkyBlue()입니까? goOutside()
  4. 중첩 삼항 연산자 예에 단점이 있습니까 :

    isTheSkyBlue() ? goOutside() | { 
        isTheInternetOn() ? playVideoGame() | read() 
    } 
    
  5. 둥지은 case 문처럼 동작하도록 변경 될 수 있습니다가. 즉, => 연산자 또는 유사 연산자를 사용합니다. 예.

    isTheSkyBlue() ? goOutside() | => 
        isTheInternetOn() ? playVideoGame() | read() 
    

    심지어는 1과 2에 대답하기 위해 함께

    isTheSkyBlue() ? goOutside() | 
        isTheInternetOn() ? playVideoGame() | read() 
    

답변

3

모두 제거, 중첩 된 기능은 아주 간단합니다, 문자 ?|은 메소드 이름입니다. ?question으로 변경하고 |or으로 변경하고 Bool로 명시 적으로 추가했습니다. 이는 모습입니다 드 설탕 : if이 그렇지 않으면 무엇을 반환 할 것 인 else을 필요로하기 때문에

case class Bool(b: Boolean) { 
    def question[X](t: => X) = new { 
     def or(f: => X) = if (b) t else f 
    } 
    } 

    Bool(isTheSkyBlue()).question(goOutside()).or(
    Bool(isTheInternetOn()).question(playVideoGame()).or(read()) 
) 

3 조금 강하다는 무엇입니까? 당신은 단지 부작용을하고있는 경우에 당신은 이런 식으로 뭔가를 할 수 : 질문 4

implicit def OneWayBooleanBool(b: Boolean): OneWayBool = OneWayBool(b) 

    case class OneWayBool(b: Boolean) { 
    def ??[X](t: => X) = if (b) t 
    } 

    isTheSkyBlue() ?? goOutside() 

는 복잡한 코드를 제외하고 중첩와 실제 문제가 없습니다.

질문 5에 대해, 누군가 다른 사람이 이것을하는 방법을 알지 못한다면, scala가 어떻게 해결 될 것이기 때문에 당신은 정말로 이것을 할 수 없습니다. 노아의 대답 @ 보완

+0

새로운 {...}이 (가) 함수 "or"가있는 익명 객체를 만드는 이유는 무엇입니까? 그 다음 부울에 따라 t 또는 f를 평가합니까? 나는 그것을 훨씬 더 잘 이해했다. –

1

:

? 기능 유형 X의 값을 반환하지 않습니다, 그것은 익명의 클래스를 반환합니다. 우리는 보통의 클래스 (순간에 대한 무시 게으름) 만들 수 :

class PartiallyEvaluated[X](b: Boolean, t: X) { 
    def |(f: X) = if(b) t else f 
} 
class Bool(b: Boolean) { 
    def ?[X](t: X) = new PartiallyEvaluated(b, t) 
} 

스칼라는 항상 a.b(c).d(e)a b c d e 해결합니다. "end chain"메서드를 추가하고자한다면 첫 번째 표현식이 다른 객체에서 호출 될 때 무엇을해야 하는지를 아는 게으른 일을 반환하게 할 수 있습니다.아니면 for/yield의 사슬에 대한 구문을 만들 수도 있지만 도움이되는 것보다 혼란스러워 할 수 있습니다.