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

时间:2015-08-06 07:21:34

标签: scala implicit-conversion implicit 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
}

此代码不起作用。但这确实如此。

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
}

我想要这样的东西。

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)
}

有可能吗?

2 个答案:

答案 0 :(得分:4)

首先,你应该为implicits选择一个更精致的类型,有一个原语作为一个隐含的不是很整洁。隐式StringInt在生产代码中总是一个坏主意。现在你正在学习,所以习惯这个很好。

所以让我们说:

case class Name(name: String)

现在了解隐式传播和转发非常重要。 Implicits通过继承或更高范围传播,因此您要么扩展具有您正在寻找的隐式的东西,要么将其导入更高的范围。

最好在secound的函数参数组中定义implicits,如下所示:

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

这是因为当您使用parantheses调用函数whoAmI时,编译器会期望显式传递隐式,这会使使用含义无效。

所以当你写这个whoAmI时:

def whoAmI(implicit name: Name): Unit

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

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()
}

答案 1 :(得分:1)

你应该指定,NewPerson.whoAmI采用隐式参数,它将在Person.whoAmI中使用

 class Person {

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

  class NewPerson {
    def whoAmI()(implicit name: String): 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)
  }