【问题标题】:Add method to library with scala implicit使用 scala 隐式将方法添加到库
【发布时间】:2012-02-26 22:12:56
【问题描述】:

我想在库类中添加新函数“extra”(例如“orig”)。

orig.extra(rich.Arg()) // <- like this

如果我评论第一次隐式转换,就会出错。我阅读了 Scala 规范,并怀疑有两个地方可以进行隐式查找:

  1. 参数的伴随对象

  2. 持有参数的对象

有什么建议吗?不幸的是,大多数关于隐式的官方文档都不是很有帮助,而且堆栈溢出搜索也是如此。

scala> object container {
 |   //implicit def orig2rich(o: orig.type) = new { def extra(a: rich.Arg) = "extra" }
 |   object rich {
 |     implicit def orig2rich(o: orig.type) = new { def extra(a: Arg) = "extra" }
 |     case class Arg(val some: String = "some")
 |     object Arg {
 |       implicit def orig2rich(o: orig.type) = new { def extra(a: Arg) = "extra" }
 |     }
 |   }
 |   object orig {
 |     def standard(s: String) = "standard"
 |   }
 |   orig.extra(rich.Arg())
 | }
<console>:35: error: value extra is not a member of object container.orig
     orig.extra(rich.Arg())

编辑

我读过Where does Scala look for implicits?,非常有用。并找到我的案例 - 参数类型的隐式范围

有效的例子:

object container {
class A(val n: Int) {
  def +(other: A) = new A(n + other.n)
}
object A {
  implicit def fromInt(n: Int) = new A(n)
}

// This becomes possible:
1 + new A(1)
// because it is converted into this:
A.fromInt(1) + new A(1)
}

稍微改一下,只是函数名(我真正想要的),和:-(哎呀

object container {
class A(val n: Int) {
  def hello(other: A) = new A(n + other.n)
}
object A {
  implicit def fromInt(n: Int) = new A(n)
}

// This becomes possible:
1.hello(new A(1))
// because it is converted into this:
A.fromInt(1).hello(new A(1))
}

<console>:16: error: value hello is not a member of Int
       1.hello(new A(1))

Scala 版本 2.9.1.r0-b20120114153402(OpenJDK 64 位服务器 VM,Java 1.6.0_22)。

这有点令人困惑。我试着混合

7.3 次观看

  1. 在类型为 T 的 e 的选择 e.m 中,如果选择器 m 不表示成员 的 T 。在这种情况下,搜索适用于 e 并且其结果的视图 v 包含一个名为 m 的成员。搜索继续在隐式的情况下 参数,其中隐式范围是 T 之一。如果找到这样的观点, 选择 e.m 转换为 v (e ).m。
  2. 在类型为 T 的 e 的选择 e.m(args) 中,如果选择器 m 表示某个 mem- T 的 ber(s) ,但这些成员都不适用于参数 args。在 在这种情况下,搜索适用于 e 的视图 v,其结果 con- 包含适用于 args 的方法 m。搜索继续进行 隐式参数的情况,其中隐式范围是

恕我直言,这是不可能的

谢谢

【问题讨论】:

标签: scala implicit-conversion


【解决方案1】:

scala 正在应用在同一范围内可见的隐式转换,因此您只需添加行

import rich.orig2rich

import rich._

此代码将起作用

object container {

  //implicit def orig2rich(o: orig.type) = new { def extra(a: rich.Arg) = "extra" }
  object rich {
    implicit def orig2rich(o: orig.type) = new {
      def extra(a: Arg) = "extra"
    }

    case class Arg(val some: String = "some")

    object Arg {
      implicit def orig2rich(o: orig.type) = new {
        def extra(a: Arg) = "extra"
      }
    }

  }

  object orig {
    def standard(s: String) = "standard"
  }

  import rich.orig2rich

  def test = orig.extra(rich.Arg())
}

println(container.test)

【讨论】:

    【解决方案2】:

    问题可能是origrichrichimplicit def 的加载顺序。

    顺便说一句,下面的代码工作正常,我先定义了orig而不是rich,最后将implicit转换为皮条客orig

    object container {
        object orig {
                def standard(s:String) = "standard"
        }
    
        object rich {
                case class Arg(val some: String = "some")
    
                object Arg {
                        implicit def orig2rich(o: orig.type) = new { def extra(a: Arg) = "extra" }
                }
        }
    
        implicit def orig2rich(o: orig.type) = new { def extra(a: rich.Arg) = "extra" }
    
        orig.extra(rich.Arg())
    }
    
    println(container.orig.extra(container.rich.Arg()))
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-01-04
      • 2011-08-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-23
      相关资源
      最近更新 更多