【问题标题】:Can I specialise a functions type parameters in Scala like I can with C++ template specialisation?我可以像使用 C++ 模板专业化一样在 Scala 中专门化函数类型参数吗?
【发布时间】:2012-07-25 16:48:52
【问题描述】:

我想编写一个根据其类型参数表现不同的函数。 我想要的一个简单示例如下所示:

def f[Int] = "I'm an int"
def f[Float] = "I'm a float"
def f[Burger] = "You want fries with that?"

这在 Scala 中是否可行,还是我需要解决一些问题?

【问题讨论】:

    标签: scala types parameters


    【解决方案1】:

    不是直接的;在 Scala 中执行此操作的常用方法是使用类型类。

    trait FAble[T] { def doF: String }
    object FAble {
      implicit val fInt = new FAble[Int] { def doF = "I'm an int" }
      implicit val fFloat = new FAble[Float] { def doF = "I'm a float" }
      implicit val fBurger = new FAble[Burger] { def doF = "You want fries?" }
    }
    
    def f[T](implicit ev: FAble[T]) = ev.doF
    // or
    def f[T: FAble] = implicitly[FAble[T]].doF
    

    它有点冗长,但它也有一些优点——可以计算隐式实例(使用implicit defs 而不是vals),并且任何给定类型都可以有多个实例,它允许您通过在代码的不同点具有不同的实例在范围内来选择行为。

    您不能以 C++ 方式执行此操作的原因是 Scala 泛型不涉及为不同类型参数生成代码(@specialized 除外,因为它也无法执行您想要的操作)。所以说“嘿编译器,当你在那个位置看到一个 Int 时,不要从通用模板生成代码,而是使用这个特定的代码”是没有意义的。

    【讨论】:

      【解决方案2】:

      另一种可能的方法是使用证据:

      def f[T](t:T)(implicit ev: T<:<Float) {
      
      // float version 
      
      }
      
      def f[T](t:T)(implicit ev: T<:<Int) {
      
      // int version 
      
      }
      

      不过我会推荐类型类作为更优雅的解决方案

      【讨论】:

        【解决方案3】:

        您可能想查看宏:http://scalamacros.org/。宏是在编译期间运行的自定义函数,可以根据编译时计算动态生成代码。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2015-07-05
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2018-07-31
          • 1970-01-01
          相关资源
          最近更新 更多