Эмуляция! = В Scala с использованием <> - PullRequest
3 голосов
/ 20 октября 2010

Я пытаюсь подражать! = С <> в Scala.

implicit def conditional[A](left : A) = new {
 |   def<>[A](right : A) = (left != right)
 | }

В каком случае эта эмуляция не будет работать

Ответы [ 2 ]

7 голосов
/ 21 октября 2010

Это должно работать всегда, но, возможно, не так, как вы себе представляете.Ожидаете ли вы, что два типа будут одинаковыми?Если это так, это должно быть

class Conditionalize[A](left: A) { def <>(right: A) = left != right }
implicit def conditional[A](left: A) = new Conditionalize(left)

, если нет, то лучше использовать отдельный параметр типа:

implicit def notequality[A](a: A) = new { def <>[B](b: B) = a != b }

Первый будет работать только в том случае, если LHS не требуется неявнопреобразован в тот же тип, что и RHS.С условным, но не определяемым качеством примечания:

implicit def int_to_string(i: Int) = i.toString
scala> "5" <> 5
res0: Boolean = false

scala> 5 <> "5"
<console>:9: error: type mismatch;
 found   : java.lang.String("5")
 required: Int
       5 <> "5"

, поскольку вы не можете связать импликации.

Последний случай будет работать так же, как! =.(Правка: с одним особым случаем, связанным со значением null, из-за его типа Null.)

Оба из них обернут примитивы, что замедлит работу в тяжелых условиях.Но Scala избегает странностей Java, где 0.0 == -0.0, но (new java.lang.Double(0.0)).equals(new java.lang.Double(-0.0)) ложно, поэтому вы не должны замечать разницу в результате.

И если вы хотите, вы можете добавить @specialized, чтобы сделатькомпараторы избегают боксерских примитивов за счет дополнительного размера кода.

4 голосов
/ 21 октября 2010

Следует обратить внимание на то, что <> имеет приоритет, отличный от ==, поэтому некоторые вещи не будут работать без скобок.Например:

a <> b >> 2  // (a <> b) >> 2
a != b >> 2  // a != (b >> 2)
...