Скала неприменить, что возвращает логическое значение
Читая это, у меня все еще есть вопросы о unapply()
это возвращает Boolean
,
Если вы посмотрите книгу Scala Programming Book (2-е издание), стр. 602. Вот пример:
case Email(Twice(x @ UpperCase()), domain) => ...
Где UpperCase определен как объект, который имеет unapply()
возврате Boolean
и не имеет apply()
object UpperCase {
def unapply(s:String): Boolean = s.toUpperCase == s
}
куда Twice
это что-то вроде этого:
object Twice {
def apply(s:String): String = s + s
...
Вопросы (должно быть слишком много, извините за это):
Как UpperCase(). Unapply(..) работает здесь?
Если я прохожу: DIDI@hotmail.com
, затем x
в первом фрагменте кода = 'DI'.. затем мы используем '@' .. для связывания 'x', чтобы передать его UpperCase.unapply
вызывать unapply(x)
т.е. unapply('DIDI')
(?) Потом возвращается True
,
Но почему нет Option
? Я склонен думать, что unapply
возвращается Option
.. один из способов, как это работает. Это, вероятно, потому что обычно Option
переносит некоторые данные, но для простого случая мы НЕ должны переносить логическое значение? А потому что у нас нет apply()?
Какая разница, когда используете Boolean
/ Option
? На основании этого примера.
И этот синтаксис: x @ UpperCase()
, это должно заменить value match case
(таким образом, как я полагаю, чтобы прочитать его?) синтаксис, если мы сопоставляем внутри одного конкретного case
? Это не кажется унифицированным способом / синтаксисом для этого.
Обычно такой синтаксис (при условии, что x,y - Int): case AA(x @ myX, y) => println("myX: " + myX)
Говорит, что x
привязывается к myX
, в принципе myX
псевдоним x
.. в этом случае. Но в нашем случае - x @ UpperCase()
, x
привязывается к UpperCase().unapply()
.. положить x
в качестве параметра. Я имею в виду связывание здесь довольно абстрактное / широкое понятие..
2 ответа
Это просто:
1) Если вы вернете логическое значение, ваше приложение не проверяет только соответствующий запрос
scala> object UpperCase {
| def unapply(s: String) = s.toUpperCase == s
| }
defined module UpperCase
scala> "foo" match {
| case UpperCase() => true
| case _ => false
| }
res9: Boolean = false
2) Если вы возвращаете Option [T], вы создаете экстрактор, который разворачивает T
scala> object IsUpperCase {
| def unapply(s: String) = Option(s).map(x => x.toUpperCase == x)
| }
defined module IsUpperCase
scala> "FOO" match {case IsUpperCase(flag) => flag}
res0: Boolean = true
Это не так просто.
Поведение совпадения "логический тест" только что изменилось за последнюю веху:
apm@mara:~/clones/scala$ ./build/pack/bin/scala
Welcome to Scala version 2.11.0-20130911-042842-a49b4b6375 (OpenJDK 64-Bit Server VM, Java 1.7.0_25).
Type in expressions to have them evaluated.
Type :help for more information.
scala>
scala> object OK { def unapply(s: String) = Some(s) filter (_ == "OK") }
defined object OK
scala> import PartialFunction._
import PartialFunction._
scala> cond("OK") { case OK() => true }
<console>:12: error: wrong number of patterns for object OK offering String: expected 1, found 0
cond("OK") { case OK() => true }
^
<console>:12: error: wrong number of patterns for object OK offering String: expected 1, found 0
cond("OK") { case OK() => true }
^
scala> cond("OK") { case OK(x) => true }
res1: Boolean = true
scala> :q
Ранее вы могли использовать экстрактор без извлечения каких-либо полей, просто для "логического теста", даже если результат unapply
не является Boolean
:
apm@mara:~/clones/scala$ scalam
Welcome to Scala version 2.11.0-M4 (OpenJDK 64-Bit Server VM, Java 1.7.0_25).
Type in expressions to have them evaluated.
Type :help for more information.
scala> import PartialFunction._
import PartialFunction._
scala> object OK { def unapply(s: String) = Some(s) filter (_ == "OK") }
defined object OK
scala> cond("OK") { case OK() => true }
res0: Boolean = true
scala> cond("OK") { case OK(x) => true }
res1: Boolean = true
Вот некоторые обсуждения, а также изменение способа обработки подписей экстрактора.