【问题标题】:Default type for method calls方法调用的默认类型
【发布时间】:2011-10-01 12:18:58
【问题描述】:

我想知道在 Scala 中调用类型参数化方法时是否可以使用默认类型。假设我在某处有以下方法:

def apply[A]( id: String )( implicit processor: Processor[A] ) =
  processor( data get id )

我希望 A 成为 String,当编译器没有提示要推断什么类型时。所以我可以重载我的定义:

def apply( id: String )( implicit processor: Processor[String] ) =
  processor( data get id )

但是两种方法在擦除后都会有相同的签名......有没有办法提供默认类型?

【问题讨论】:

    标签: generics scala types type-parameter


    【解决方案1】:

    您可以通过定义以下幻像类型来实现此目的:

    sealed class DefaultsTo[A, B]
    trait LowPriorityDefaultsTo {
       implicit def overrideDefault[A,B] = new DefaultsTo[A,B]
    }
    object DefaultsTo extends LowPriorityDefaultsTo {
       implicit def default[B] = new DefaultsTo[B, B]
    }
    

    那么你的方法就可以写出来了

    def apply[A]( id: String )( implicit e: A DefaultsTo String,
                                         processor: Processor[A] ) =
       processor( data get id )
    

    overrideDefault 的定义保证对于任何两个指定类型,AB,编译器始终可以提供类型为 DefaultsTo[A, B] 的对象(例如 DefaultsTo[Int, String])。但是,如果未指定这两种类型之一(例如DefaultsTo[A, String]),编译器将更愿意识别这两种类型(在示例中提供DefaultsTo[String, String],从而推断String 为未指定类型A )。

    作为Naftoli Gugenheim pointed out in this mailing list thread,您还可以实现一些用于上下文边界的漂亮语法:

    class Has[B] {
       type AsDefault[A] = A DefaultsTo B
    }
    
    def apply[A : Has[String]#AsDefault : Processor](id: String) =
       implicitly[Processor[A]].apply(data get id)
    

    【讨论】:

    【解决方案2】:

    在这种情况下你可以使用一个小技巧

    class C {
       def apply[A](id: String) = (processor: Processor[A]) => id + processor
       def apply(id: String)(implicit processor: Processor[String]) = id + processor
    }
    

    在更一般的情况下,不知道...

    编辑

    我忘了你需要 processorimplicit 所以它不会编译...

    【讨论】:

    • 如果他希望编译器隐式提供处理器,那是行不通的。
    猜你喜欢
    • 1970-01-01
    • 2022-10-13
    • 2014-05-13
    • 1970-01-01
    • 1970-01-01
    • 2018-08-28
    • 2016-10-12
    • 2017-12-01
    • 2023-03-09
    相关资源
    最近更新 更多