代码之家  ›  专栏  ›  技术社区  ›  hbatista

尝试扩展泛型数组

  •  3
  • hbatista  · 技术社区  · 16 年前

    我很确定这在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]
    

    我错过了什么?

    4 回复  |  直到 16 年前
        1
  •  6
  •   Eastsun    16 年前

    只要我的两分钱:

    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>
    
        2
  •  3
  •   hbatista    16 年前

    问我自己的问题,我需要的是 视图绑定 (对我来说是新的,仍在学习)在数组类型上,修改如下代码:

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

    这表明存在从T类型到可打印类型的隐式转换(视图),与执行此操作相同:

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

    不确定这是否是最好的方法,欢迎提出任何改进建议!

        3
  •  1
  •   Randall Schulz    16 年前

    为了 a.print() Byte PrintableByte 另一个来自 Array[PrintableByte] PrintableArray

        4
  •  0
  •   Arjan Blokzijl    16 年前

    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
    
    推荐文章