代码之家  ›  专栏  ›  技术社区  ›  0__

按名称调用参数和函数类型不匹配

  •  0
  • 0__  · 技术社区  · 14 年前

    在以下场景中,按名称参数会导致与函数发生冲突。

    给定一些序列化基础结构:

    trait Tx {
       def readSource[A](implicit ser: Serializer[A]) : Source[A] = 
          new Source[A] { 
             def get(implicit tx: Tx): A = ser.read(new In {})
          }
    }    
    trait In
    trait Source[A] { def get(implicit tx: Tx): A }
    trait Serializer[A] { def read(in: In)(implicit tx: Tx): A }
    

    以及一个示例类型及其序列化程序:

    // needs recursive access to itself. for reasons
    // beyond the scope of this questions, `self` must
    // be a by-name parameter
    class Transport(self: => Source[Transport])
    
    // again: self is required to be by-name
    def transportSer(self: => Source[Transport]) : Serializer[Transport] = 
       new Serializer[Transport] { 
          def read(in: In)(implicit tx: Tx): Transport = new Transport(self)
       }
    

    现在想象一个名为 Hook 其处理递归/相互连通性:

    trait Hook[A] {
       def source: Source[A]
    }
    

    及其序列化程序:

    def hookSer[A](peerSelf: Source[A] => Serializer[A]) : Serializer[Hook[A]] = 
       new Serializer[Hook[A]] {
          def read(in: In)(implicit tx: Tx) : Hook[A] =
             new Hook[A] with Serializer[A] {
                val source: Source[A] = tx.readSource[A](this)
                def read(in: In)(implicit tx: Tx) : A = peerSelf(source).read(in)
             }
       }
    

    则以下操作失败:

    val hs = hookSer[Transport](transportSer)
    
    <console>:15: error: type mismatch;
     found   : => Source[Transport] => Serializer[Transport]
     required: Source[Transport] => Serializer[Transport]
              val hs = hookSer[Transport](transportSer)
                                          ^
    

    如何在不按名称将参数更改为函数的情况下(尽可能)解决此问题?

    1 回复  |  直到 14 年前
        1
  •  0
  •   0__    14 年前

    似乎一个人可以写类型 (=> Source[A]) => Serializer[A] 以下为:

    def hookSer[A](peerSelf: (=> Source[A]) => Serializer[A]) : Serializer[Hook[A]] = ...
    
    val hs = hookSer[Transport](transportSer)
    val h  = hs.read(new In {})(new Tx {})
    val t  = h.source.get(new Tx {})
    
    推荐文章