2015-12-29 2 views
2

У меня есть следующий код:Оптимизация псевдонима типа, пропускающая неявное преобразование в Scala?

type RString = String 

    implicit def stringToRString(s:String):RString = s.reverse 

    val s = "The Force Awakens" 
    val r:RString = s 

    println(r) 

I рода ожидаемый r быть обратным s но оно равно s. Является ли этот компилятор scala ярлыком, поскольку RString является псевдонимом String, поэтому неявное преобразование никогда не называется?

ответ

4

Вам не нужен псевдоним, но маркерный признак или тег для перевернутых строк.

scala> trait Reversed 
defined trait Reversed 

scala> def cv(s: String): String with Reversed = 
    | s.reverse.asInstanceOf[String with Reversed] 
cv: (s: String)String with Reversed 

scala> implicit def cv(s: String): String with Reversed = 
    | s.reverse.asInstanceOf[String with Reversed] 
warning: there was one feature warning; re-run with -feature for details 
cv: (s: String)String with Reversed 

scala> val r: String with Reversed = "hi" 
r: String with Reversed = ih 
5

Алиас типа не вводит новый тип, это псевдоним. Вы можете заменить левую и правую стороны. Таким образом, r: RString совпадает с r: String, поэтому преобразование не требуется.

Вам нужно будет что-то вроде этого:

object RString { 
    // allow RString to be used as a String 
    implicit def toString(r: RString): String = r.toString 
} 
implicit class RString(val peer: String) extends AnyVal { 
    override def toString = peer.reverse 
} 

val s = "The Force Awakens" 
val r: RString = s // "snekawA ecroF ehT" 

То есть, RString нового типа, класс значения, которое переворачивает строку.

+0

'AnyVal' не предотвращает выделение здесь. –

+0

Почему это не предотвращено? –

+0

@ som-snytt, возможно, вы правы; не уверен. Для этого я могу использовать [unboxed tagged types] (http://etorreborre.blogspot.co.uk/2011/11/practical-uses-for-unboxed-tagged-types.html). –