如何将隐式值传递给函数?

edd*_*ark 1 scala implicit implicit-conversion implicits

我是新手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"
    def whoAmI: Unit = {
        val p: Person = new Person
        p.whoAmI
    }
}

object Main extends App {
    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{
    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()(name)
}
Run Code Online (Sandbox Code Playgroud)

是否可以?

fla*_*ian 5

首先,您应该为隐式选择更精细的类型,将原始类型作为隐式并不是很整洁。AStringInt隐式在生产代码中总是一个坏主意。现在你正在学习,所以习惯这一点很好。

所以假设我们有:

case class Name(name: String)
Run Code Online (Sandbox Code Playgroud)

现在了解隐式传播和转发很重要。隐式通过继承或更高的范围传播,因此您可以扩展具有您正在寻找的隐式的内容,或者将其导入更高的范围。

最好在第二组函数参数中定义隐式,如下所示:

def test(p1: T1, p2: T2..)(implicit ev1: E1, ev2: E2): ReturnType = {}
Run Code Online (Sandbox Code Playgroud)

这是因为当您调用whoAmI带有括号的函数时,编译器期望显式传递隐式,这使使用隐式的重点无效。

所以当你这样写时whoAmI

def whoAmI(implicit name: Name): Unit
Run Code Online (Sandbox Code Playgroud)

您可以这样调用:whoAmI()使用(), 编译器希望您手动传递名称。隐式是“隐藏的”,这意味着一旦定义它们就意味着“就在那里”,只要您遵守范围规则,它们就可以用来消除打字样板。

class Person {

    def whoAmI()(implicit name: Name): Unit = {
        println(s"I am ${name.name}")
    }
}

class NewPerson {
    // Here your implicit is mising
    def whoAmI()(implicit name: Name): Unit = {
        val p: Person = new Person
        p.whoAmI
    }
}

object Main extends App {
    implicit val name: Name = Name("a Shamir")
    val person: NewPerson = new NewPerson
    // Now you don't actually need to manually type in the implicit
    person.whoAmI()
}
Run Code Online (Sandbox Code Playgroud)