我写了几个看起来像这样的函数:
def myWrite(os: OutputStream) = {}
def myWrite(w: Writer) = {}
现在两者都非常相似,我想我会尝试编写该函数的单个参数化版本。
我从一个类型开始,它具有 Java OutputStream 和 Writer 中常见的两种方法:
type Writable[T] = {
def close() : Unit
def write(cbuf: Array[T], off: Int, len: Int): Unit
}
一个问题是 OutputStream 写入
Byte
和作家写道Char
,所以我用 T
参数化了类型.然后我写我的函数:
def myWrite[T, A[T] <: Writable[T]](out: A[T]) = {}
并尝试使用它:
val w = new java.io.StringWriter()
myWrite(w)
结果:
<console>:9: error: type mismatch;
found : java.io.StringWriter
required: ?A[ ?T ]
Note that implicit conversions are not applicable because they are ambiguous:
both method any2ArrowAssoc in object Predef of type [A](x: A)ArrowAssoc[A]
and method any2Ensuring in object Predef of type [A](x: A)Ensuring[A]
are possible conversion functions from java.io.StringWriter to ?A[ ?T ]
myWrite(w)
我尝试了其他几种类型和参数的组合,但到目前为止都无济于事。
我的问题是是否有办法实现这一目标,如果有,如何实现。
(注意 myWrite 的实现需要在内部知道参数化 write() 方法的类型
T
,因为它需要像在 new ArrayT 中一样创建一个缓冲区。)更新:“正确”的解决方案不起作用,因为编译器中存在错误:https://lampsvn.epfl.ch/trac/scala/ticket/2672
最佳答案
首先,你不需要参数化A
在 myWrite
.您的目标类不是通用的!其次,您不需要明确允许子类——只需让继承为您解决问题。
def myWrite[T](out: Writable[T]) = {}
现在该方法可以推断类型
T
.只要您出于某种原因不需要 A
的真实类型此外,这对您有用:myWrite(new StringWriter)
但是,您将遇到一个问题:
def myWrite[T](out: Writable[T]) = new Array[T](0) // Doesn't work!
问题是这是通用代码。不知道是什么
T
是——它可以是任何东西!所以你需要告诉编译器传入标识T
的信息:def myWrite[T : ClassManifest](out: Writable[T]) = new Array[T](0)
(编辑:简化了答案以使其实际工作。)
(编辑:实际上,它不太有效——请参阅评论。)
关于scala - 编写一个可以接受 Writer 和 OutputStream 的通用函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4702664/