标签: implicits

如何将工厂方法添加到Scala中的现有Java类

在纯Scala环境中,如果我想将工厂方法"添加"到现有对象,我可以执行以下操作:

object Test

object Extensions {

    object RichTest {
        def someFactory = new Test()
    }
    implicit def fromTest(t: Test.type) = RichTest

}

...

import Extensions._
val t = Test.someFactory
Run Code Online (Sandbox Code Playgroud)

我需要将这样的功能与现有的Java类结合使用.在我的具体的例子,我想一个工厂方法添加fromLocation到类com.google.android.maps.GeoPoint(和我想每一个Android开发者就会知道为什么这将是有益的;-)).

但是,如果我尝试做类似的事情

implicit def fromGeoPoint(t: GeoPoint.type) = RichTest
Run Code Online (Sandbox Code Playgroud)

我收到一个错误说明

类型不匹配; 发现:com.google.android.maps.GeoPoint.type(底层类型对象为com.google.android.maps.GeoPoint)必需:AnyRef

所以我想知道是否有任何方式可以实现上述方法 - 或者提供隐式转换Location是否GeoPoint是Scala中的首选方式,因此Location可以在GeoPoint需要时使用?


根据评论中的要求,使用场景:

// Callback you get from the GPS
override def onLocationChanged(l: Location) {
    // You want to put a marker on a map, hence a …
Run Code Online (Sandbox Code Playgroud)

java scala implicits

9
推荐指数
1
解决办法
1218
查看次数

Scala:导入如何防止发现隐含值?

我可以使用调试隐式的建议:

我想使用隐含的,x:

type T
trait HasT {
  implicit def x: T = ...
}
Run Code Online (Sandbox Code Playgroud)

但我还需要从某个包中导入通配符foo.我尝试了两种不同的方式来介绍两者:

class UseT extends HasT {
  import foo._
  implicitly[T] // fails! "could not find implicit value"
  // use foo stuff
}
Run Code Online (Sandbox Code Playgroud)

class UseT {
  object hasT extends HasT
  import hasT.x
  import foo._
  implicitly[T] // fails! "could not find implicit value"
}
Run Code Online (Sandbox Code Playgroud)

两者都失败了"找不到"(不是"模糊的含义值").

x: T通过继承或导入在方法调用点访问隐式标识符时会发生这种情况.

我的解决方法是在导入之前将x重新绑定到隐式val.以下两项工作:

implicit val x2: T = implicitly[T]
import foo._
implicitly[T] // works!
Run Code Online (Sandbox Code Playgroud)

implicit val …
Run Code Online (Sandbox Code Playgroud)

scope scala shadowing implicits slick

9
推荐指数
1
解决办法
900
查看次数

暧昧的暗示

问题是为什么下面的代码不能用于类型推断(下面是一个REPL会话来演示),它可以修复吗?更具体地说,这与编译器用于推断返回类型的CanBuildFrom的使用有何不同?

鉴于此代码:

object S {
    import java.net._

    trait UrlLike[T] {
      def url(s: String): T
    }

    object UrlLike {
      implicit object str extends UrlLike[String]{def url(s: String) = s}
      implicit object url extends UrlLike[URL]{def url(s: String) = new URL(s)}
      implicit object uri extends UrlLike[URI]{def url(s: String) = new URI(s)}
    }

    trait UrlSupport {
        val _url: String

        def url[T : UrlLike]: T = implicitly[UrlLike[T]].url(_url)
    }
}
Run Code Online (Sandbox Code Playgroud)

我在REPL(2.8.1)中有这个会话:

scala> :load c:\temp\UrlTest.scala
Loading c:\temp\UrlTest.scala...
defined module S

scala> import java.net._
import java.net._

scala> import S._ …
Run Code Online (Sandbox Code Playgroud)

scala implicits

8
推荐指数
2
解决办法
1088
查看次数

方法与Scala中的函数和含义

让我们声明一个def和一个等价函数作为val:

scala> def optional(x:Int):Option[String] = None
optional: (x: Int)Option[String]

scala> val optional2:(Int)=>Option[String] = (i:Int) => None
optional2: Int => Option[String] = <function1>
Run Code Online (Sandbox Code Playgroud)

现在为什么这不起作用?

scala> List(1).flatMap(optional2)
<console>:9: error: type mismatch;
 found   : Int => Option[String]
 required: Int => scala.collection.GenTraversableOnce[?]
              List(1).flatMap(optional2)
                              ^
Run Code Online (Sandbox Code Playgroud)

虽然这两个都做到了吗?

scala> List(1).flatMap(optional)
res4: List[String] = List()

scala> List(1).flatMap(optional2(_))
res5: List[String] = List()
Run Code Online (Sandbox Code Playgroud)

由于Option不是GenTraversableOnce的子类型,我认为这必须与implicits有关,但我无法弄清楚究竟是什么.我正在使用Scala 2.9.1.

scala option implicits

8
推荐指数
1
解决办法
310
查看次数

函数隐式参数在将其传递给更高阶函数后不再如此

在Scala中,您可以执行以下操作:

def foo(implicit v: Int) = println(v);
def h(x: Int) = { implicit val i: Int = x; foo }

h(42)
> 42
Run Code Online (Sandbox Code Playgroud)

hcall将foo引用作为闭包.

尝试传递fooh参数并不奇怪:

def g(x: Int)(f: Int => Unit) = { implicit val i: Int = x; f }
Run Code Online (Sandbox Code Playgroud)

但它不会起作用:

g(1)(foo)
> error: could not find implicit value for parameter v: Int
Run Code Online (Sandbox Code Playgroud)

我认为它正在发生的是foo被称为实际参数的评估.是对的吗?

当传递具有普通参数列表的函数(非隐式)时,不会评估该函数:

def foo2(v: Int) = println("Foo2")
g(1)(foo2)
> Int => Unit = <function1>
Run Code Online (Sandbox Code Playgroud)

这是预期结果,并且foo2 …

scala function implicit implicits

8
推荐指数
1
解决办法
163
查看次数

使用Mapper和Implicit Operators有什么好处吗?

Mapper Automap:

Mapper.CreateMap<ObjectType1, ObjectType2>()
    .ForMember(o1 => o1.PropName, mapper => mapper.MapFrom(o2 => o2.Prop2Name));

Mapper.Map(object1, object2);
Run Code Online (Sandbox Code Playgroud)

隐含运算符:

public static implicit operator Object1(Object2 o2)
{ 
    Object1 o1 = new Object2(); 
    //Mapping code here...
    return o1;
}
Run Code Online (Sandbox Code Playgroud)

c# implicit-cast automapper implicits

7
推荐指数
1
解决办法
1106
查看次数

scala隐式导致StackOverflowError

这个隐式val如何导致StackOverFlowError?

(削减我的原始代码,仍然导致错误)

object Complicit {
  // a class with name, default, and conversion function as implicit val
  case class CC[A](name: String, defaultValue: A)(implicit val convert: String => A) {
    def getFrom(s: String): A= try { 
      convert(s) 
    } catch { 
      case t: Throwable => 
        println("ERROR: %s".format(t))  // just to see the StackOverflowException
        defaultValue
    }
  }  

  // this works fine
  object Works {
    val cc1= CC("first", 0.1)(_.toDouble)
  } 

  // this causes java.lang.StackOverflowError due to the implicit
  object Fails {
    // !!! StackOverFlowError …
Run Code Online (Sandbox Code Playgroud)

stack-overflow scala implicits

7
推荐指数
1
解决办法
420
查看次数

上下文绑定有两个通用参数

在Scala中,我可以使用上下文边界:

def sort[T : Ordered](t: Seq[T])
Run Code Online (Sandbox Code Playgroud)

意思是:

def sort[T](t: Seq[T])(implicit def Ordered[T])
Run Code Online (Sandbox Code Playgroud)

如果我有一个包含两个通用参数的类怎么办?即我希望能够确保我有一个Writer[T, String].是否有一种语法,我可以使用上下文边界(T : ...)或我需要显式隐式(这是有趣的写).

scala implicits

7
推荐指数
1
解决办法
543
查看次数

Scala隐式转换在某些条件下应用,但在其他条件下不适用

这是一个简单的重现器,我在其中定义了一个带有隐式重新排序转换的"可交换"对类型.如果函数的参数f位于预先存在的命名值(t在示例中),则编译器会按预期应用隐式转换.但是,如果我尝试f直接调用literal CommutativePair,它会因类型错误而失败.在这种情况下,编译器不应用隐式重新排序转换.

object repro {
  import scala.language.implicitConversions

  case class CommutativePair[A, B](a: A, b: B)

  object CommutativePair {
    // Support a kind of commutative behavior via an implicit reordering
    implicit def reorderPair[B, A](pair: CommutativePair[B, A]) =
      CommutativePair(pair.b, pair.a)
  }

  // The idea is to allow a call to 'f' with Pair[Int, String] as well,
  // via implicit reorder.
  def f(p: CommutativePair[String, Int]) = p.toString

  val t = CommutativePair(3, "c")

  // This works: the implicit …
Run Code Online (Sandbox Code Playgroud)

scala implicit compiler-bug implicit-conversion implicits

7
推荐指数
1
解决办法
341
查看次数

为什么Scala隐式解析对于带有类型参数的重载方法失败?

第一个示例成功找到了对方法的隐式转换foo(String),但是只要我添加一个类型参数(请参阅fails参考资料),编译就不再解析它了:

object works {
  class A {
    def foo(): String = ???
  }
  implicit class PimpedA(a: A) {
    def foo(i: String): String = ???
  }
  val a = new A()
  a.foo("test") //compiles
}

object fails { //same as `works`, but adds type parameter
  class A {
    def foo[T](): String = ???
  }
  implicit class PimpedA(a: A) {
    def foo[T](i: String): String = ???
  }
  val a = new A()
  PimpedA(a).foo("test") // compiles
  a.foo("test") // error: too …
Run Code Online (Sandbox Code Playgroud)

scala type-conversion implicits

7
推荐指数
1
解决办法
692
查看次数