如何在Scala中计算默认构造函数参数?

时间:2018-01-27 12:44:21

标签: java scala constructor default-parameters

在Java中我会写:

class MyClass {

   private static String id_state;

   final String id;

   MyClass(String id) {
      if( id != null ) {
         this.id = id;
      }
      else {
         this.id = /// complex computation using id_state
      }
   }

   MyClass() {
      this(null);
   }

}

我如何在Scala中编写类似内容?

6 个答案:

答案 0 :(得分:3)

您可以在scala中拥有多个参数列表:

class Foo(x: Option[String])(
  val bar: String  = x.getOrElse(computeDefault)
)

(不要在scala中使用null,它们是邪恶的,而是使用Option

这样做的缺点是在创建实例时必须添加一组额外的括号:

val foo = new Foo(None)()

或者,您可以拥有一个"静态工厂"实例化类的方法:

class Foo(val bar: String) 
object Foo {
   def apply(x: Option[String] = None) = new Foo(x.getOrElse(computeDefault))
}

您现在可以创建Foo的实例,例如val foo = Foo(None)val foo = new Foo("bar")val foo = Foo()

最后,你可以有两个构造函数:

class Foo(val bar: String) {
   def this(x: Option[String] = None) = this(x.getOrElse(computeDefault))
}

如果你坚持允许null(我强烈建议不要这样做),最后一种方法不会起作用(因为参数类型是相同的),但是你可以这样做:< / p>

 class Foo(x: String = null) {
   val bar = Option(x).getOrElse(computeDefault)
 }

答案 1 :(得分:2)

您可以在构造函数声明中提供默认值,如下所示:

class MyClass (val id: String = "One ID to rule them all")

来源:https://docs.scala-lang.org/tour/default-parameter-values.html

答案 2 :(得分:2)

其他两个答案的组合,使用默认参数并执行与Java代码匹配的构造函数,如下所示:

class MyClass (_id : String = null){
  val id = 
    if (_id == null){
      "complexString" 
    }
    else{
      _id
    }
}

因为在Scala中,你应该避免使用null值,你可以选择这样做:

class MyClass (_id : Option[String]){
  val id = _id.getOrElse({
    "complexcomputation"
  })
}

并通过MyClass(None)MyClass(Some("String"))

创建对象

答案 3 :(得分:1)

作为对其他答案的略微简化,我建议:使用默认值Option。这样您就可以将其称为new Foo(Some("x"))new Foo()

class Foo(_id:Option[String]=None) {
  val id = _id.getOrElse({ "42" }) 
}

如果很可能空字符串不是可接受的值,那么这可能是一个更简单的解决方案 - 尽管可能不是“惯用”。这样您就不需要Some(),因此您可以将其用作:new Foo("x")new Foo()

class Foo(_id:String = "") {
  val id = if (_id != "") _id else { "42" } 
  // use "id" here ... 
}

编辑:我已经内联了“昂贵的计算”"42"以避免在实例化期间进行方法调用。

答案 4 :(得分:0)

如果您希望将代码“1到1”翻译为scala,它将如下所示:

class MyClass (private val _id:String){ // default constructor, keeping _id private

  val id:String= //everything that happens in java inside the constructor happens in scala inside the class body
    if( _id != null ) {
       _id
    }
    else {
      /// complex computation using id_state
      ""
    }



    def this() { // alternate constructors are created by defining a function named this
        this(null)
    }

}

object MyClass{ //Companion Object replaces static methods and properties
  val id_state:String = "test"
}

答案 5 :(得分:0)

我认为您应该假设您的方法的调用者理解Scala约定不使用null。这个答案试图查看Java类的潜在用例,将它们提炼为一些简单的规则,然后开发简单的惯用Scala来解决这些用例。

以下代码涵盖两个用例:

  • 调用者已经知道他们想要使用的ID
  • 来电者希望您为他们生成ID
case class MyClass(id: String)

object MyClass {
  def apply(): MyClass = MyClass(myComplexComputation)
  def myComplexComputation: String = ???
}