我是新手scala。我正在学习implicit variables。如何将隐式变量传递给调用另一个将使用该变量的函数的函数。我知道这个问题看起来很愚蠢。看看我写的代码就知道了。
class Person{
def whoAmI(implicit name: String): Unit = {
println(s"I am $name")
}
}
class NewPerson{
def whoAmI: Unit = {
val p: Person = new Person
p.whoAmI
}
}
object Main extends App {
implicit val name: String = "a Shamir"
val person: NewPerson = new NewPerson
person.whoAmI
}
Run Code Online (Sandbox Code Playgroud)
此代码不起作用。但这确实。
class Person{
def whoAmI(implicit name: String): Unit = {
println(s"I am $name")
}
}
class NewPerson{
implicit val name: String = "a Shamir" …Run Code Online (Sandbox Code Playgroud) 我正在使用Predef带有-Yno-predef标志的自定义。它基本上是SlamData 的副本。
当我尝试展平嵌套的 immutable Seqs 集合时,我收到错误:
No implicit view available from my.Predef.Seq[String] => scala.collection.GenTraversableOnce[String].
Run Code Online (Sandbox Code Playgroud)
如果我把import scala.Predef._它再次编译。我试图调查scala.Predef并scala打包对象,但是当我试图复制TraversableOnce's, Traversable's 或Seq's 的定义时,它没有帮助。
有人知道 vanilla predef 的哪一部分负责生成这个隐式吗?
假设我想要一个提供square方法的整数。
科特林:
fun Int.square() = this * this
Run Code Online (Sandbox Code Playgroud)
用法:
println("${20.square()}")
Run Code Online (Sandbox Code Playgroud)
文档:
扩展实际上并不修改它们扩展的类。通过定义扩展,您不会将新成员插入到类中,而只是使新函数可以使用这种类型的变量上的点符号调用。
我们要强调的是,扩展函数是静态调度的
我的期望是他们在编译期间只是将它添加到扩展类的成员函数中,但这是他们明确否认的,所以我的下一个想法是它可能“有点”像 scala 隐式。
斯卡拉:
object IntExtensions{
implicit Class SquareableInt(i:Int){
def square = i*i
}
}
Run Code Online (Sandbox Code Playgroud)
用法:
import IntExtensions._
Run Code Online (Sandbox Code Playgroud)
进而
println(f"${20.square}")
Run Code Online (Sandbox Code Playgroud)
文档:
隐式类被脱糖为类和隐式方法配对,其中 implciit 方法模仿类的构造函数。
生成的隐式方法将与隐式类同名。
但是 scala 隐式创建了一个新类,这将禁用this.
那么...... Kotlin 是如何扩展类的呢?“使可调用”并没有告诉我太多。
有两种方法可以链接共享库。
一种称为隐式动态链接,一种称为显式动态链接。
我在谷歌上搜索了一些文档,但没有找到说明两者效率差异的文档。
以 linux .so 文件为例。我的疑问是:隐式链接与显式方式相比,显式方式会以某种方式导致更多的 IO 或 cpu 或内存吗?
想知道哪种方法更有效,为什么?
多谢 !
我是 Scala 的初学者,我正试图将我的头脑围绕在发散的隐式扩展上。
这是我的玩具代码:
class FooList[T](implicit ord: Ordering[T]) {
}
class Human(val score: Int) extends Ordering[Human] {
override def compare(x: Human, y: Human): Int = {
return x.score.compareTo(y.score);
}
}
object Main {
def main(args: Array[String]): Unit = {
val h = new Human(100)
val lst = new FooList[Human]();
}
}
Run Code Online (Sandbox Code Playgroud)
我收到一个错误:
diverging implicit expansion for type Ordering[Human]
starting with method comparatorToOrdering in trait LowPriorityOrderingImplicits
not enough arguments for constructor FooList: (implicit ord: Ordering[Human])FooList[Human].
Unspecified value parameter ord.
Run Code Online (Sandbox Code Playgroud)
https://scastie.scala-lang.org/wkSrZ6BMQKW9ZJrsZhlITQ
我希望在正确的方向上有一两个指针:)
我有一个带有函数的简单代码,它获取weakTypeOf case 类并返回其字段,可以预见我们得到2 个项目列表
def getMembers[T: WeakTypeTag] =
weakTypeOf[T].members.filterNot(_.isMethod).toList
final case class Person(name: String, age: Int) extends Models
val fields = getMembers[Person]
println(fields.length) // 2
Run Code Online (Sandbox Code Playgroud)
它工作正常
但是,如果我想在创建子对象类时从将 Person 作为类型参数传递的 trait 中获取成员呢?(WeakTypeTag 在构建过程中无法传递给 trait)
trait ModelManager[CCT] {
def getMembers: List[String] = ???
}
case object PersonManager extends ModelManager[Person]
val fields = PersonManager.getMembers
println(fields.length)
Run Code Online (Sandbox Code Playgroud)
有没有办法从 CCT 参数中获取 weakTypeOf ?
我正在自己学习 Scala 并遇到了这个问题。继Link的优秀答案之后,假设我有以下代码:
object Example extends App {
val x = Seq(1, 2, 3)
val y = Seq("1", "2", "3")
class Or[A, B]
implicit def orA[A, B](implicit ev: A): Or[A, B] = new Or
implicit def orB[A, B](implicit ev: B): Or[A, B] = new Or
def f1[T](seq: Seq[T])(implicit ev: Or[T =:= Int, T =:= String]) = {
println(seq)
}
f1(Seq(1, 2, 3))
f1(Seq("1", "2", "3"))
}
Run Code Online (Sandbox Code Playgroud)
这编译得很好。但是现在让我们假设我更改了函数,以便它需要一个序列列表,而不仅仅是序列,然后尝试以下操作:
object Example extends App {
val x = Seq(1, 2, 3) …Run Code Online (Sandbox Code Playgroud) 我有一个类似于下面的代码的 Scala 代码。在类/对象级别有一个隐式定义,我想用方法中定义的隐式“覆盖”它。(如果您真的需要知道,我需要ExecutionContext专门针对所讨论的方法更改我的内容)。
在这个例子中,我想在方法的范围内b用作隐式 for 。我怎样才能做到这一点?Intbar
object Foo {
implicit val a: Int = 1
def bar: Int = { // Didn't pass implicit Int parameter
implicit val b: Int = 2
implicitly[Int]
}
}
Run Code Online (Sandbox Code Playgroud)
这抱怨
错误:不明确的隐式值:Int 类型的对象 Foo 中的值 a 和 Int 类型的值 b 均匹配预期的 Int 类型
所以我认为 Scala 不能在隐式类范围和隐式方法范围之间进行选择。
我正面临这个与 Scala 隐式解析相关的奇怪问题
这是代码片段
import scala.collection.Factory
import scala.collection.immutable.Seq
sealed trait A
sealed trait B
case class BImpl() extends B
case class AImpl() extends A
object implicitsContainer {
type AB = (A, B)
implicit def toStringAnyTuples[C[X] <: Iterable[X], A <: AB]
(col: C[A])
(implicit factory: Factory[(String, Any), C[(String, Any)]])
: C[(String, Any)] = {
factory.fromSpecific(col.iterator.map(f => f._1.toString -> f._2))
}
}
object Main extends App {
import implicitsContainer._
def a(f: Seq[(String, Any)]): Seq[(String, Any)] = f
val w: Seq[(AImpl, BImpl)] = …Run Code Online (Sandbox Code Playgroud) 这个帖子:
描述了现代 Scala 编译器使用的隐式搜索优先级和算法。在上面的列表中,直接导入的隐式函数应该比关联类型中的作用域具有更高的优先级(例如在伴随对象中定义)
这条规则大部分时间都有意义,直到直接导入的 Predef.scala 开始干扰:
case class A(v: Int)
object A {
implicit class AFns(self: A) {
def +(v2: Int): A = A(self.v + v2)
}
}
val a1 = A(3)
val b = a1 + 4
assert(b == A(7))
Run Code Online (Sandbox Code Playgroud)
上面的示例应该可以成功编译,但是 Predef 中定义的所有类的 + 运算符覆盖主导了场景,并导致所有带有 + 运算符的扩展无用(除非在更严格的范围内明确导入)。这很烦人,有没有办法在 Predef 中禁用隐式或“降级”其优先级?
以上实验已在scala 2.12.12 & 2.13.3中进行