Есть | (или) короткое замыкание при сопоставлении с образцом в Scala?

Я заметил, что нет || оператор доступен при сопоставлении с образцом - есть | короткое замыкание?

2 ответа

Решение

При сопоставлении с образцом | короткое замыкание Ты не можешь позвонить unapply или подобное (с возвращенными параметрами) с оператором или, где побочные эффекты могут быть более вероятными. Таким образом, короткое замыкание является чисто техникой оптимизации (не повлияет на правильность кода, за исключением исключительных случаев, таких как метод равных побочных эффектов). Это означает, что вы ограничены в своей способности короткого замыкания или нет по причинам производительности или побочных эффектов.

Чтобы увидеть это, если мы напишем этот код:

def matchor(s: String) = s match {
  case "tickle" | "fickle" => "sickle"
  case _ => "hammer"
}

Мы видим этот байт-код (частично)

public java.lang.String matchor(java.lang.String);
  Code:
   0:   aload_1
   1:   astore_2
   2:   ldc #12; //String tickle
   4:   aload_2
   5:   astore_3
   6:   dup
   7:   ifnonnull   18
   10:  pop
   11:  aload_3
   12:  ifnull  25
   15:  goto    31
   18:  aload_3
   19:  invokevirtual   #16; //Method java/lang/Object.equals:(Ljava/lang/Object;)Z
   22:  ifeq    31
   25:  iconst_1
   26:  istore  4
   28:  goto    66
   31:  ldc #18; //String fickle
   33:  aload_2
   ...
   66:  iload   4
   68:  ifeq    78
   71:  ldc #20; //String sickle
   73:  astore  6
   75:  goto    82
   ...
   82:  aload   6
   84:  areturn

Посмотрите прыжок на линии 28, чтобы избежать тестирования "fickle" дело? Это короткое замыкание.

| короткие замыкания.

object First {
    def unapply(str: String): Boolean = {
        println("in First")
        str == "first"
    }
}

object Second {
    def unapply(str: String) = {
        println("in Second")
        str == "second"
    }
}

object Run extends App {
    "first" match {
        case First() | Second() => None
    }

    //Output: In First

    "first" match {
        case Second() | First() => None
    }

    //Output: In Second\nIn First
}
Другие вопросы по тегам