2010-07-01 4 views
3

Я уверен, что это очень просто сделать в Scala, но я не могу понять, какие намеки система типов должна сделать этой работой.Пытается расширить общий массив

Я хочу иметь абстрактный класс для печати, а затем неявно преобразовывать в него другие классы. Более конкретно, я хочу неявно преобразовать Byte в Printable и Array [Byte] в Printable.

Так что я сделал это:

abstract class Printable{ 
    def print():String 
} 
class PrintableByte(b:Byte) extends Printable{ 
    def print() = "" /*return something*/ 
} 
implicit def printableByte(b:Byte) = new PrintableByte(b) 

class PrintableArray(a:Array[Printable]) extends Printable{ 
    def print() = { 
     for(i <- 0 until a.length) a(i).print() // no problems here 
     "" /*return something*/ 
    } 
} 
implicit def printableArray(a:Array[Printable]) = new PrintableArray(a) 

Однако:

val b:Byte = 0 
b.print() //no problem here 
val a= new Array[Byte](1024) 
a.print() //error: value print() is not a member of Array[Byte] 

Я ожидал, что система типа будет в состоянии понять, что Array [Byte] неявно массив [Версия для печати] и неявно Printable.

Что мне не хватает?

+0

Массивы изменились коренным образом от Scala 2.7 до 2.8. Что вы используете? –

+0

Я использую 2.8 RC7 – hbatista

+0

Как вы можете видеть из ответов, это не имеет никакого отношения к тому, как работают массивы, и решение должно быть одинаковым как в Scala 2.7, так и в Scala 2.8. –

ответ

5

Просто мои два цента:

abstract class Printable{ 
    def print: String 
} 

class PrintableArray[T <% Printable](a: Array[T]) extends Printable{ 
    def print = (for(x <- a) yield x.print) mkString 
} 
implicit def printableArray[T <% Printable](a: Array[T]) = new PrintableArray(a) 

class PrintableByte(b: Byte) extends Printable{ 
    def print = "%#02x" format b 
} 
implicit def printableByte(b:Byte) = new PrintableByte(b) 

class PrintableInt(i: Int) extends Printable{ 
    def print = "%#08x" format i 
} 
implicit def printableInt(i: Int) = new PrintableInt(i) 

А потом:

scala> val b: Byte = -1 
b: Byte = -1 

scala> val i: Int = 100 
i: Int = 100 

scala> val bArr = Array[Byte](11,22,33,44) 
bArr: Array[Byte] = Array(11, 22, 33, 44) 

scala> val iArr = Array[Int](111111,222222,333333,444444) 
iArr: Array[Int] = Array(111111, 222222, 333333, 444444) 

scala> b print 
res0: String = 0xff 

scala> i print 
res1: String = 0x000064 

scala> bArr print 
res2: String = 0xb0x160x210x2c 

scala> iArr print 
res3: String = 0x01b2070x03640e0x0516150x06c81c 

scala> 
+0

В конце концов, я обнаружил * вид связанный * вещь сам, но принимаю ваш ответ! Благодаря! – hbatista

1

Для a.print() ввести проверку, два неявные преобразования потребовалось бы, один из Byte в PrintableByte, а другое от Array[PrintableByte] к PrintableArray, но implicits не будет сочетать в этой манере. Только одно неявное преобразование будет применено для того, чтобы сделать выражение, не проверяющее тип, правильно проверять тип.

0

Randall уже дал причину, почему ваш код не работает так, как он есть. В вашем случае, вы можете просто изменить свой PrintableArray следующим образом, а затем он работает, как вы описали (используя SCALA 2.8.0.RC7):


abstract class Printable{ 
    def print():String 
} 
class PrintableByte(b:Byte) extends Printable{ 
    def print() = b.toString 
} 
implicit def printableByte(b:Byte) = new PrintableByte(b) 

class PrintableArray(a:Array[Byte]) extends Printable { 
    def print() = { 
     var s:String = "" 
     for(i <- 0 until a.length) s += a(i).print() 
     s 
    } 
} 
implicit def printableArray(a:Array[Byte]) = new PrintableArray(a) 

scala> val a = new Array[Byte](10) 
a: Array[Byte] = Array(0, 0, 0, 0, 0, 0, 0, 0, 0, 0) 

scala> a print 
res0: String = 0000000000 
+0

Это работает, но это не общее. Я хочу преобразовать любой массив объектов Printable в Printable. – hbatista

3

Aswering свой вопрос здесь, что я нуждаясь был вид связан (новый для меня, все еще учится) от типа массива, изменив код так:

class PrintableArray[T <% Printable](a:Array[T]) {...} 
implicit def printableArray[T <% Printable](a:Array[T]) {...} 

Это говорится, что существует неявное преобразование (вид) от типа Т к Printable, и так же, как это делается:

class PrintableArray[T](a:Array[T])(implicit t2printable: T => Printable) {...} 
implicit def printableArray[T](a:Array[T])(implicit t2printable: T => Printable) {...} 

Не уверен, что это лучший способ сделать это, любые предложения по улучшению приветствуются!

Смежные вопросы