【问题标题】:Scala: get default values without creating an objectScala:在不创建对象的情况下获取默认值
【发布时间】:2016-03-13 15:36:06
【问题描述】:

假设构造函数中有一个具有默认值的类:

class Adapter(url: String = "127.0.0.1", port: Int = 8080)

是否可以在运行时获取这些参数的默认值而不创建此对象的实例?

请不要询问用例,这更多是关于语言本身的问题。

【问题讨论】:

    标签: scala default-value


    【解决方案1】:

    将它们移动到伴随对象中?

    case class Adapter(url: String = Adapter.defaultURL, port: Int = Adapter.defaultPort)
    
    object Adapter {
        val defaultURL = "127.0.0.1"
        val defaultPort = 8080
    }
    

    如果只能从 case class 访问默认值,则可以使用 private 限定更多默认值

    【讨论】:

    • 这不是 OP 的这个问题的答案
    • 这似乎是一个不错的答案。我不明白这个问题。如果问题是示例代码中的硬编码值,您可以轻松地想象一个 "def lookupAdapterUrl" 而不是 "val defaultURL" 。 . . .
    • 您将如何以编程方式发现它们?
    【解决方案2】:

    我假设您最感兴趣的是默认方法是如何在内部实现的。这是您的代码的 javap 反汇编(使用非常有用的 :javap <classname> scala 控制台命令:

    scala> class Adapter(url: String = "127.0.0.1", port: Int = 8080)
    defined class Adapter
    
    scala> :javap -c Adapter$ // Adapter$ because we want the companion object
    Compiled from "<console>"
    public class Adapter$ {
    
      ... 
    
      public java.lang.String $lessinit$greater$default$1();
        Code:
           0: ldc           #16                 // String 127.0.0.1
           2: areturn       
    
      public int $lessinit$greater$default$2();
        Code:
           0: sipush        8080
           3: ireturn       
    
      ...
    

    如您所见,创建默认值的方法在伴随对象中被编码为特殊命名的方法。因此,要在不重构示例的情况下调用这些方法,您必须使用反射:

    scala> Adapter.getClass.getMethod("$lessinit$greater$default$1").invoke(Adapter) 
    res8: Object = 127.0.0.1
    
    scala> Adapter.getClass.getMethod("$lessinit$greater$default$2").invoke(Adapter) 
    res9: Object = 8080
    

    显然,在生产代码中这样做可能不是一个好主意,因为名称修改细节等可能会改变。在这种情况下,只需使用@Sparko 的建议即可。

    关于名称修改方案的说明:该方案是methodName + "$default$" + parameterNumber。上例中要修饰的方法是构造函数,即“”。所以你最终得到例如"$lessinit$greater" 为方法名,"$lessinit$greater$default$0" 为方法名,用于计算第一个参数的默认值。

    【讨论】:

      猜你喜欢
      • 2011-11-20
      • 1970-01-01
      • 2014-04-01
      • 1970-01-01
      • 1970-01-01
      • 2011-04-25
      • 2013-05-19
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多