Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/scala/16.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
在Scala中,如何对伴生对象执行编译时类型检查?_Scala_Compile Time_Typechecking - Fatal编程技术网

在Scala中,如何对伴生对象执行编译时类型检查?

在Scala中,如何对伴生对象执行编译时类型检查?,scala,compile-time,typechecking,Scala,Compile Time,Typechecking,在许多语言中,但在Scala中不容易做到的一件事是: 定义原型“Super”,以便“Super”的所有实现都必须定义构造函数“create()” 我发现这个约束非常重要,并且能够在运行前发现很多问题。然而,这个特性在Java中只是部分实现(通过定义一个总是抛出错误的“抽象”静态方法),而在Scala中完全缺失(伴随对象与类完全分离,不能在原型中实现) 是否有宏或工具允许我这样做 更新很抱歉,我的问题缺少上下文和示例。下面是scala中的一个正式用例: 在项目A中,我们定义了一个可由所有子项目扩展

在许多语言中,但在Scala中不容易做到的一件事是:

定义原型“Super”,以便“Super”的所有实现都必须定义构造函数“create()”

我发现这个约束非常重要,并且能够在运行前发现很多问题。然而,这个特性在Java中只是部分实现(通过定义一个总是抛出错误的“抽象”静态方法),而在Scala中完全缺失(伴随对象与类完全分离,不能在原型中实现)

是否有宏或工具允许我这样做

更新很抱歉,我的问题缺少上下文和示例。下面是scala中的一个正式用例:

在项目A中,我们定义了一个可由所有子项目扩展的接口:

trait AbstractFoo {}
此接口应始终具有默认的0参数生成器/构造函数,因此project a可以按需对其进行初始化,但是project a不知道每个构造函数的实现:

object AbstractFoo {

  def default[T <: AbstractFoo: ClassTag](): T
}
必须满足:

  • “Foo”必须定义一个0参数的构建器/构造函数(可能在其伴生对象中)

  • 调用AbstractFoo.defaultFoo可以调用此0参数生成器/构造函数

  • 应注意,在另一种情况下,存在一种解决方案,即将每个伴生对象定义为隐式类型类:

    trait FooBuilder[T <: AbstractFoo] {
      def default(): T
    }
    
    object AbstractFoo {
    
      implicit object Foo extends FooBuilder[Foo] {
        def default() = {...}
      }
    
      def default[T <: AbstractFoo: FooBuilder](): T = {
        implicitly[FooBuilder[T]].default
      }
    }
    
    scala将引用类Foo的作用域,其中包括包含隐式值Foo的对象Foo,并最终找到0参数构造函数


    我认为这个定义比在object FooBuilder下定义要好,因为您只能定义FooBuilder一次,因此它不太可扩展。你同意我的意见吗?如果是这样,你能修改一下你的答案吗?这样我就可以给你加分了。

    我不明白为什么一个
    抽象类
    甚至一个
    特质
    都不允许这样做

    abstract class DefineCreate{
      def create(): Unit
    }
    
    case class Foo(one: Int)
    object Foo extends DefineCreate{
      def create(): Unit =  { Console.out.println("side-effect") }
    }
    
    因此,我强制用户在所讨论的
    对象上创建
    create
    方法,因为
    DefineCreate
    的所有实现都必须这样做才能编译

    更新以下评论

    不必求助于宏之类的东西,就可以用类型类实现同样的功能:

    trait Constructor[A]{
      def create(): A
    }
    
    object Construct{
      def create[A](implicit cr: Constructor[A]): A = cr.create()
    }
    

    它不会显式地强制伴随对象生成方法,但如果用户想要使用
    构造函数,它会强制用户生成类型类。创建[Foo]
    模式。

    我不明白为什么
    抽象类
    甚至
    特征
    都不允许这样做

    abstract class DefineCreate{
      def create(): Unit
    }
    
    case class Foo(one: Int)
    object Foo extends DefineCreate{
      def create(): Unit =  { Console.out.println("side-effect") }
    }
    
    因此,我强制用户在所讨论的
    对象上创建
    create
    方法,因为
    DefineCreate
    的所有实现都必须这样做才能编译

    更新以下评论

    不必求助于宏之类的东西,就可以用类型类实现同样的功能:

    trait Constructor[A]{
      def create(): A
    }
    
    object Construct{
      def create[A](implicit cr: Constructor[A]): A = cr.create()
    }
    


    这并没有显式地强制伴随对象生成方法,但如果用户想要使用
    构造函数,它确实会强制用户生成type类。创建[Foo]
    模式。

    我不认为Java中有“抽象”静态方法。静态方法是不能被重写的。Op是如此无知,但却如此确信他所说的,这有点可笑。。。我不知道他是不是在抱怨不,这是一个合理的问题(见@Wheaties回答中的评论)是的,OP不知道如何陈述他在问什么。请停止向下投票。根据您当前的界面,您需要这样调用它:
    AbstractFoo.default[ConcreteFoo]
    。在这种情况下,我认为隐式类型类模式非常适合……我不认为“抽象”静态方法在Java中是一种东西。静态方法是不能被重写的。Op是如此无知,但却如此确信他所说的,这有点可笑。。。我不知道他是不是在抱怨不,这是一个合理的问题(见@Wheaties回答中的评论)是的,OP不知道如何陈述他在问什么。请停止向下投票。根据您当前的界面,您需要这样调用它:
    AbstractFoo.default[ConcreteFoo]
    。在这种情况下,我认为隐式类型类模式非常适合……那么你怎么看1。要求所有Foo子类必须在其伴生对象中定义create()?2.仅通过类型信息类[Foo]查找函数Foo.create()?啊,现在我知道你在问什么了。你有这个用例吗?我不清楚您为什么需要它。第2点不是您在Scala中通常会做的事情。非常感谢所有的答案:)我应该很快重构我的问题,以避免更多误导。@tribbloid您的目标是什么?强制trait/接口的实现者拥有一个带有预定义参数集的“构造函数”?有一种构造特定类型对象的通用方法吗?还有别的吗?那你怎么看。要求所有Foo子类必须在其伴生对象中定义create()?2.仅通过类型信息类[Foo]查找函数Foo.create()?啊,现在我知道你在问什么了。你有这个用例吗?我不清楚您为什么需要它。第2点不是您在Scala中通常会做的事情。非常感谢所有的答案:)我应该很快重构我的问题,以避免更多误导。@tribbloid您的目标是什么?强制trait/接口的实现者拥有一个带有预定义参数集的“构造函数”?有一种构造特定类型对象的通用方法吗?还有别的吗?
    trait Constructor[A]{
      def create(): A
    }
    
    object Construct{
      def create[A](implicit cr: Constructor[A]): A = cr.create()
    }