标签: implicit

暗示太多了!

我正在编写一个2D Vector类,其声明如下:

case class Vec2(x:Float, y:Float) extends (Float, Float)(x, y) {

    def +(v:Vec2) = Vec2(v.x+x, v.y+y)
    //Subtract, dot product, projection, etc.
    ...
    ...
}
Run Code Online (Sandbox Code Playgroud)

我希望能够写出像Vec2(3, 7) + (2, 9)我写的那样的东西

scala> implicit def ii2v2(i:(Int, Int)) = Vec2(i._1, i._2)
ii2v2: (i: (Int, Int))org.zhang.lib.misc.Vec2

scala> Vec2(2, 6) + (3, 1)
res25: org.zhang.lib.misc.Vec2 = (5.0,7.0)
Run Code Online (Sandbox Code Playgroud)

大.但是,如果我尝试Vec2(3, 7) + (2.6f, 9.3f),隐含将不起作用,因为(Float, Float)不匹配(Int, Int).我想出的唯一解决方案就是写出四个暗示(Int,Int), (Int, Float), (Float, Int), and (Float, Float).

当你试图考虑双打或者写一个Vec3类时,这个问题会变得荒谬.有没有解决的办法?我可以只是Vec2-ify所有东西,但我的一部分真的想要添加(Int,Int)到Vec2 :)

scala tuples vector implicit

2
推荐指数
1
解决办法
272
查看次数

隐含范围

作为我的其他问题的后续内容,请参阅代码中的注释/问题:

case class Implicit(name: String)

def foo(implicit i: Implicit = null) = println(Option(i))

def bar1(implicit i: Implicit) {
  foo // prints None
  implicit val i = Implicit("J") // Why is call to foo above affected although this line comes after?
  foo // prints Some(Implicit(I))
}

def bar2(implicit i: Implicit) {
  foo // prints None
  implicit val i = null
  implicit val j = Implicit("J")
  foo // prints None // Why? Should raise ambiguous implicits or at least choose …
Run Code Online (Sandbox Code Playgroud)

scope scala implicit

2
推荐指数
1
解决办法
508
查看次数

适用于所有Traversable子类(包括Array)的隐式类

我遇到了一个问题,试图创建一个适用于所有Traversable子类(包括Array)的隐式类.我在Scala 2.11.1和2.10.4中尝试了以下简单示例:

implicit class PrintMe[T](a: Traversable[T]) {
  def printme = for (b <- a) print(b)
}
Run Code Online (Sandbox Code Playgroud)

据我所知,这应该允许隐式转换为PrintMe,以便可以在任何Traversable上调用printme,包括List和Array.例如:

scala> List(1,2,3).printme
123
// Great, works as I expected!

scala> Array(1,2,3).printme
<console>:23: error: value printme is not a member of Array[Int]
              Array(1,2,3).printme
// Seems like for an Array it doesn't!

scala> new PrintMe(Array(1,2,3)).printme
123
// Yet explicitly building a PrintMe from an Array works 
Run Code Online (Sandbox Code Playgroud)

这里发生了什么?为什么隐式转换适用于List而不是数组?

我知道有一些技巧适应java Arrays但是从http://docs.scala-lang.org/overviews/collections/overview.html查看下面的图片看起来似乎Array的行为就像Traversable的子类.

scala.collection.immutable

arrays scala implicit scala-2.10 scala-2.11

2
推荐指数
1
解决办法
354
查看次数

隐式转换,它将属性添加到类型,而不是类型的实例

我正在阅读一些较旧的Scala帖子以更好地理解类型类,我遇到了一个似乎非常有用的,但这个例子似乎已经过时了.

有人可以帮我找出正确的方法来做Phillipe的意图吗?这是代码

trait Default[T] { def value : T }

implicit object DefaultInt extends Default[Int] {
  def value = 42
}

implicit def listsHaveDefault[T : Default] = new Default[List[T]] {
  def value = implicitly[Default[T]].value :: Nil
}

default[List[List[Int]]]
Run Code Online (Sandbox Code Playgroud)

复制/粘贴并在REPL中运行时,我得到这个>

    scala> default[List[List[Int]]]
    <console>:18: error: not found: value default
                  default[List[List[Int]]]
                  ^
Run Code Online (Sandbox Code Playgroud)

scala implicit typeclass

2
推荐指数
1
解决办法
151
查看次数

Scala Type Erasure对case类如何解决

我有一个特征和两个扩展它的案例类:

trait Authenticatable {
  val email: String
  val pass: String
  val id: Long
  val sessionid: String
}

case class Admin(
  id: Long,
  email: String,
  pass: String,
  sessionid: Option[String] = None) extends Authenticatable

case class Client(
  id: Long,
  email: String,
  pass: String,
  sessionid: Option[String] = None) extends Authenticatable
Run Code Online (Sandbox Code Playgroud)

我有函数应该验证用户,用新的sessionid复制对象并返回它.

  def auth(email: String, password: String): Try[Admin] ={
    checkPass(models.Admin.findBy(sqls"email = $email"), password)
  }

  def auth(email: String, password: String, customer: Customer): Try[Customer] ={
    checkPass(models.Customer.findBy(sqls"email = $email"), password)
  }

  private def checkPass (model: Option[Authenticatable], password: …
Run Code Online (Sandbox Code Playgroud)

scala implicit

2
推荐指数
1
解决办法
90
查看次数

是否为每个隐式类转换创建了新的类实例?

object test extends App {
  implicit class f(i: Int) { println("!!!"); def f = 42 + i }
  1.f
  2.f
  3.f
}
Run Code Online (Sandbox Code Playgroud)

在.class文件中我们看到

public static test$f f(int);
  Code:
     0: getstatic     #16                 // Field test$.MODULE$:Ltest$;
     3: iload_0
     4: invokevirtual #42                 // Method test$.f:(I)Ltest$f;
     7: areturn
Run Code Online (Sandbox Code Playgroud)

所以,看起来有一个静态方法,但这段代码打印"!!!" 跑步时3次.每个隐式类转换都有新的类实例化吗?如果是,为什么?如果不是,为什么"!!!" 打印三次?

scala implicit

2
推荐指数
1
解决办法
270
查看次数

默认参数值总是胜过 Scala 中的隐式吗?

def foo(implicit i: Int = 1) = i
def bar(implicit j: Int) = foo()

bar(4)
Run Code Online (Sandbox Code Playgroud)

这段代码的计算结果为1. 因此默认值优先于隐式的j,后者被实例化为4。因此,似乎至少在这个例子中,默认参数值胜过implicit,使得 的定义foo等价于def foo(i: Int = 1) = i

默认参数值总是胜过隐式吗?如果是,为什么这个代码是合法的(因为它令人困惑)?如果不是,反例是什么?

有没有办法获得其他行为,即与上述类似的一段代码(具有默认值 for i)将评估为4,而无需显式传递参数?

scala implicit default-parameters

2
推荐指数
1
解决办法
313
查看次数

在函数中需要Scala隐式类

我的目标是为各种类型(时间戳,日期等)配备他们默认可能没有的好的属性(订购, - 等).我正在做这样的事情:

trait NiceProperties[T] {
  def -(t: T): Double
  def +(d: Double): T
  ...
}

implicit class BetterTimestamp(val t: Timestamp) extends NiceProperties[Timestamp] {
  override def -(Timestamp): ...
}
Run Code Online (Sandbox Code Playgroud)

这一切都正常,直到我需要将它传递给一个假定的函数NiceProperties:

def myUtil[T](t: NiceProperties[T]): T = {
  (t + 1.0) + 1.0
}
Run Code Online (Sandbox Code Playgroud)

这现在失败了,因为函数缺少隐式证据表明类T可以隐式向上转换NiceProperties[T],所以它不能添加(t + 1.0): T到double.

有没有办法将隐式类的证据传递给函数?或者,有更好的模式吗?

scala implicit

2
推荐指数
1
解决办法
77
查看次数

Scala Implicit Search

In the Scala with Cats:

import scala.concurrent.{Future, ExecutionContext}
implicit def futureFunctor
  (implicit ec: ExecutionContext): Functor[Future] = …
Run Code Online (Sandbox Code Playgroud)

Whenever we summon a Functor for Future , either directly using Functor.apply or indirectly via the map extension method, the compiler will locate futureFunctor by implicit resolu on and recursively search for an ExecutionContext at the call site. This is what the expansion might look like:

// We write this:
Functor[Future]
// The compiler expands to this first:
Functor[Future](futureFunctor)
// And then to …
Run Code Online (Sandbox Code Playgroud)

scala future implicit scala-cats

2
推荐指数
1
解决办法
68
查看次数

Scala Map 的 get vs apply 操作:“类型不匹配”

我正在学习 Scala 并发现以下内容:

List(('a', 1)).toMap get 'a'           // Option[Int] = Some(1)
(List(('a', 1)).toMap) apply 'a'       // Int = 1
(List(('a', 1)).toMap)('a')            // Error: type mismatch;
                                          found   : Char('a')
                                          required: <:<[(Char, Int),(?, ?)
                                          (List(('a', 1)).toMap)('a')
Run Code Online (Sandbox Code Playgroud)

但是然后将其分配给变量再次起作用。

val b = (List(('a', 1)).toMap)
b('a') // Int = 1
Run Code Online (Sandbox Code Playgroud)

为什么会这样?

标准文档给出:

ms get k

与映射 ms 中的键 k 关联的值作为选项,如果未找到则为 None。

ms(k) (或,写出,ms apply k

与映射 ms 中的键 k 关联的值,如果未找到则为异常。

为什么第三行不起作用?

scala implicit syntactic-sugar

2
推荐指数
1
解决办法
381
查看次数