Scala中隐式参数的两种不同用法?

Tom*_*Tom 5 scala implicit

(我对Scala还是陌生的,希望这不是一个愚蠢的问题。)

据我所知,为函数声明参数implicit两种(相关但完全不同)的用法:

  1. 当编译器可以找到唯一合适的值(在调用范围内)传递时,它使在调用给定函数时显式地传递相应的参数成为可选操作。

  2. 它使参数本身成为传递具有隐式参数的其他函数的合适值(当从给定函数中调用它们时)。

在代码中:

def someFunction(implicit someParameter: SomeClass) = {  // Note `implicit`
  ...
  // Note no argument supplied in following call;
  // possible thanks to the combination of
  // `implicit` in `someOtherFunction` (1) and
  // `implicit` in line 1 above (2)
  someOtherFunction
  ...
}

def someOtherFunction(implicit someOtherParameter: SomeClass) = {
  ...
}

implicit val someValue = new SomeClass(...)
// Note no argument supplied in following call;
// possible thanks to `implicit` (1)
someFunction
Run Code Online (Sandbox Code Playgroud)

这似乎有些奇怪,不是吗?implicit从第1行删除会导致两个调用(someFunction从其他位置到和someOtherFunction从内部someFunction)都无法编译。

这背后的原理是什么?(编辑:我的意思是,如果可以在某些Scala官方资源中找到任何官方依据,则是什么。)

并且有一种方法可以在没有其他函数的情况下实现一个目标(也就是说,允许隐式传递参数给函数,而在调用其他函数时不允许在函数内隐式使用参数,和/或在调用函数时隐式使用非隐式参数)。调用其他功能)?(编辑:我稍微改变了这个问题。此外,为了澄清,我的意思是是否存在一种允许这种语言的语言构造- 无法通过手动阴影或类似方法达到效果。)

Ale*_*nov 4

对于第一个问题

这背后的理由是什么?

答案可能是基于意见的。

有没有一种方法可以实现两者兼而有之?

是的,尽管如果您想实际使用该参数,这比我最初想象的要棘手一些:

def someFunction(implicit someParameter: SomeClass) = {
  val _someParameter = someParameter // rename to make it accessible in the inner block

  { 
    val someParameter = 0 // shadow someParameter by a non-implicit
    someOtherFunction // doesn't compile
    someOtherFunction(_someParameter) // passed explicitly
  }
}
Run Code Online (Sandbox Code Playgroud)