Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/340.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何定义方法返回的结构类型_Java_Scala_Structural Typing - Fatal编程技术网

Java 如何定义方法返回的结构类型

Java 如何定义方法返回的结构类型,java,scala,structural-typing,Java,Scala,Structural Typing,我有许多Builders,它们来自库,源代码是用Java自动生成的,超出了我的控制范围。这些Builders彼此不相关,但它们有许多结构完全相同的方法 package a.b public class Builder { public Builder setA(xxx) {} public Builder setB(yyy) {} } package a.c public class Builder { public Builder setA(xxx) {}

我有许多
Builder
s,它们来自库,源代码是用Java自动生成的,超出了我的控制范围。这些
Builder
s彼此不相关,但它们有许多结构完全相同的方法

package a.b

public class Builder {
    public Builder setA(xxx) {}
    public Builder setB(yyy) {}
}

package a.c

public class Builder {
    public Builder setA(xxx) {}
    public Builder setB(yyy) {}
}
使用Scala的结构类型,如何返回生成器本身

type StructurallyBuilder = {
    def setA(xxx): StructurallyBuilder
    def setB(yyy): StructurallyBuilder
}

当我想在
structuralybuilder
上使用setA和setB时,编译器抱怨它无法解决问题。

这并不简单,但我相信您可以使用来实现这一点:

type StructurallyBuilder[F <: StructurallyBuilder[F]] = {
  def setA(xxx: Int): F
  def setB(yyy: Int): F
}

可以将实际生成器设置为结构类型的类型参数:

import scala.language.reflectiveCalls
import scala.language.existentials

type StructurallyBuilder[T <: AnyRef] = AnyRef {
  def setA(xxx): T
  def setB(yyy): T
}
导入scala.language.reflectCalls
导入scala.language.existentics

输入structuralybuilder[T为什么不使用这个.type

type StructurallyBuilder = {
    def setA(x: Int): this.type
    def setB(y: Double): this.type
}
此类用法的示例:

object App
{

  class A {
    def setA(x: Int): this.type = { this }
    def setB(y: Double): this.type = { this }
  }

  type StructurallyBuilder = {
    def setA(x: Int): this.type
    def setB(y: Double): this.type
  }


  def main(args: Array[String]):Unit =
  {
    val a = new A()
    if (a.isInstanceOf[StructurallyBuilder]) {
       System.out.println("qqq")
    }
    System.out.println(a)
   }

}
然后,尝试运行:

[info] Running X.App 
qqq
X.App$A@8f59676

可能不那么容易:(并按照那里的链接问题)谢谢。这越来越近了。我已经尝试过了,但是当我试图调用
setA(10,new a.c.Builder())
时,我遇到了编译器错误。它说“类型不匹配,预期的structuralybuilder[notexperedt],实际的a.c.Builder”。如果我把
setA[a.c.Builder]
it expect structuralybuilder[a.c.Builder]@Wins Hm,此代码对我有效:它也适用于具有相同签名的Java类:
package a.c;公共类生成器{public Builder setA(int xxx){return this;}public Builder setB(int yy){return this;}
也许你的对象与签名不完全对应?@Wins还有,似乎Sascha Kolberg是对的。你甚至不需要F-有界多态性。也可以查看我的编辑。谢谢它终于起作用了。我在代码中遗漏的是
setA
setB
中的参数是另一个
生成器的泛型。你的带有F-限制多态性的原始答案是正确的。不是后一个。因为
此.type
将返回周围
structuralybuilder
的类型。我不想返回拥有
structuralybuilder
的类,我想返回
structuralybuilder
它本身并没有按照我的需要工作。我需要什么需要的是,您可以执行类似于
builder.setA(1.setB(“B”)
type StructurallyBuilder = {
    def setA(x: Int): this.type
    def setB(y: Double): this.type
}
object App
{

  class A {
    def setA(x: Int): this.type = { this }
    def setB(y: Double): this.type = { this }
  }

  type StructurallyBuilder = {
    def setA(x: Int): this.type
    def setB(y: Double): this.type
  }


  def main(args: Array[String]):Unit =
  {
    val a = new A()
    if (a.isInstanceOf[StructurallyBuilder]) {
       System.out.println("qqq")
    }
    System.out.println(a)
   }

}
[info] Running X.App 
qqq
X.App$A@8f59676