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

Scala 如何将隐式值传递给函数?,scala,implicit-conversion,implicit,implicits,Scala,Implicit Conversion,Implicit,Implicits,我是新来的scala。我正在学习隐式变量。一个函数如何将一个隐式变量传递给调用另一个将要使用该变量的函数的函数。我知道这个问题看起来很愚蠢。看看我写的代码 class Person{ def whoAmI(implicit name: String): Unit = { println(s"I am $name") } } class NewPerson{ def whoAmI: Unit = { val p: Person = new

我是新来的
scala
。我正在学习
隐式变量
。一个函数如何将一个隐式变量传递给调用另一个将要使用该变量的函数的函数。我知道这个问题看起来很愚蠢。看看我写的代码

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

有可能吗?

您应该指定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)
  }

您应该指定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)
  }

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

因此,假设我们有:

case class Name(name: String)
现在,理解隐式传播和转发非常重要。隐式通过继承或更高的作用域进行传播,因此您可以扩展具有要查找的隐式的内容,或者将其导入到更高的作用域中

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

def test(p1: T1, p2: T2..)(implicit ev1: E1, ev2: E2): ReturnType = {}
这是因为,当您使用parantesses调用函数
whoAmI
时,编译器希望显式传递隐式,这使得使用隐式的要点无效

因此,当您编写
whoAmI
时,如下所示:

def whoAmI(implicit name: Name): Unit
您可以这样调用:
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()
}

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

因此,假设我们有:

case class Name(name: String)
现在,理解隐式传播和转发非常重要。隐式通过继承或更高的作用域进行传播,因此您可以扩展具有要查找的隐式的内容,或者将其导入到更高的作用域中

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

def test(p1: T1, p2: T2..)(implicit ev1: E1, ev2: E2): ReturnType = {}
这是因为,当您使用parantesses调用函数
whoAmI
时,编译器希望显式传递隐式,这使得使用隐式的要点无效

因此,当您编写
whoAmI
时,如下所示:

def whoAmI(implicit name: Name): Unit
您可以这样调用:
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()
}

如果我想保持Person和NewPerson类的原样呢?那有可能吗?如果我想保持Person和NewPerson类的原样呢?那有可能吗?如果我想保持Person和NewPerson类的原样呢?那么有可能吗?@eddard.stark,没有,因为在person对象的
NewPerson
类中调用
whoAmi
时,您没有告诉编译器从何处获取隐式表达式。您可以执行类似于
class NewPerson()(implicit ev:Name){..}
的操作,例如将隐式放在构造函数中,但您需要以某种方式提供它。是否可以在不更改
NewPerson
的情况下执行此操作?如果我想保持Person和NewPerson类的原样,该怎么办?那么有可能吗?@eddard.stark,没有,因为在person对象的
NewPerson
类中调用
whoAmi
时,您没有告诉编译器从何处获取隐式表达式。您可以执行类似于
class NewPerson()(implicit ev:Name){..}
的操作,例如将隐式放在构造函数中,但您需要以某种方式提供它。是否可以在不更改
NewPerson
的情况下执行此操作?