如何在只接受子类的scala中进行结构类型化?

如何在只接受子类的scala中进行结构类型化?,scala,types,class-hierarchy,structural-typing,Scala,Types,Class Hierarchy,Structural Typing,与其用文字描述问题,不如让我向您展示一个Scala解释器会话,它显示了我想要做的事情 scala> class A extends Parent{ | def name = "Alex" | } defined class A scala> class B extends Parent{ | def name = "Bernardo" | } defined class B

与其用文字描述问题,不如让我向您展示一个Scala解释器会话,它显示了我想要做的事情

    scala> class A extends Parent{
         | def name = "Alex"
         | }
    defined class A

    scala> class B extends Parent{
         | def name = "Bernardo"
         | }
    defined class B

    scala> def addFamilyName[T <: Parent](fn:String, c:T{def name():String}) = c.name + " " + fn
    addFamilyName: [T <: Parent](fn: String, c: T{def name(): String})java.lang.String

    scala> addFamilyName( "Martins", new A())
    <console>:11: error: type mismatch;
     found   : A
     required: ?{def name(): String}
           addFamilyName( "Martins", new A())
                             ^
scala>A类扩展父级{
|def name=“Alex”
| }
定义的A类
scala>B类扩展了父类{
|def name=“Bernardo”
| }
定义的B类

scala>def addFamilyName[T信不信由你,问题就在方法签名的括号中。这是有效的:

def addFamilyName[T <: Parent](fn:String, c:T{def name:String}) =
    c.name + " " + fn

哇。真是……出人意料!?!你知道我可以读一些东西来理解为什么吗?不管怎样,下次我遇到这样的问题,我会在问之前尝试添加和删除括号。谢谢。@Alexandre我恐怕不知道为什么。我怀疑这是为了防止返回函数的方法出现歧义,但我不确定。@AlexandreMartins如果类型为
def name()=“Bernardo”
,这将很好地工作,例如
def name
def name()
不同,尽管我不知道适用的SLS/原因。@AlexandreMartins pst说需要将
name
定义为
name()
(这确实有效:我试过了!)这个问题可能会提供一些线索:这是不同的方法。Paulp曾尝试让structural type同时接受这两种方法,但Odersky断然拒绝了。方法
name
name()不相同。调用后者可以用前者的语法来完成,它们是不同的和结构类型,特别是,不认为它们是相同的。
def addFamilyName(fn:String, c:Parent{def name:String}) =
    c.name + " " + fn