如何在 Scala 中用另一个方法包装一个具有隐式的方法?
How to wrap a method having implicits with another method in Scala?
我有一个隐含的方法:
def f(x: String)(implicit dispatcher: ExecutionContextExecutor, mat: ActorMaterializer) = ???
我想创建一个辅助方法,例如:
def g1(y: String) = f("uri1" + y)
def g2(y: String) = f("uri2" + y)
当然,对于方法g
,这不能编译为no implicits found for parameter ex: ExecutionContext
。
我不想在 g
中重复 implicits
声明。
那么,这种情况的惯用解决方案是什么?
惯用的解决方案是重复隐式参数。
如果您多次重复同一组隐式参数,那么惯用的解决方案是引入您的类型 class(或只是单个隐式)而不是那组隐式并使用此类型 class .
不是惯用的解决方案是引入将为方法生成隐式参数部分的宏注释。
有时您可以将隐式传输到更高的某个级别
class MyClass(implicit val ec: ExecutionContext) extends ExecutionContextAware {
def f(x: String) = ???
def g(y: String) = f("xxx" + y)
}
trait ExecutionContextAware {
implicit def ec: ExecutionContext
}
或
trait MyTrait extends ExecutionContextAware {
def f(x: String) = ???
def g(y: String) = f("xxx" + y)
}
object Impl extends ExecutionContextAware {
implicit def ec: ExecutionContext = ExecutionContext.Implicits.global
}
trait ExecutionContextAware {
implicit def ec: ExecutionContext
}
Could you please also give an example with typeclass?
假设你有多个类型 classes
trait TC1[A] {
def foo = ???
}
trait TC2[A] {
def bar = ???
}
你必须在方法中重复它们
def f[A](implicit tc1: TC1[A], tc2: TC2[A]) = ???
1.然后可以介绍一下你的类型class
trait TC[A] {
def foo
def bar
}
通过TC1
、TC2
、...
表达
object TC {
implicit def mkTC[A](implicit tc1: TC1[A], tc2: TC2[A]): TC[A] = new TC[A] {
def foo = tc1.foo
def bar = tc2.bar
}
}
并使用它
def f[A](implicit tc: TC[A]) = ???
2. 替代方法是
trait TC[A] {
implicit def tc1: TC1[A]
implicit def tc2: TC2[A]
}
object TC {
implicit def mkTC[A](implicit _tc1: TC1[A], _tc2: TC2[A]): TC[A] = new TC[A] {
implicit def tc1: TC1[A] = _tc1
implicit def tc2: TC2[A] = _tc2
}
}
def f[A](implicit tc: TC[A]) = {
import tc._
???
}
在您使用 ExecutionContextExecutor
、ActorMaterializer
的示例中(例如按照第二种方法),您可以引入
trait MyImplicit {
implicit def dispatcher: ExecutionContextExecutor
implicit def mat: ActorMaterializer
}
并替换
def f(x: String)(implicit dispatcher: ExecutionContextExecutor, mat: ActorMaterializer) = ???
和
def f(x: String)(implicit mi: MyImplicit) = {
import mi._
???
}
我有一个隐含的方法:
def f(x: String)(implicit dispatcher: ExecutionContextExecutor, mat: ActorMaterializer) = ???
我想创建一个辅助方法,例如:
def g1(y: String) = f("uri1" + y)
def g2(y: String) = f("uri2" + y)
当然,对于方法g
,这不能编译为no implicits found for parameter ex: ExecutionContext
。
我不想在 g
中重复 implicits
声明。
那么,这种情况的惯用解决方案是什么?
惯用的解决方案是重复隐式参数。
如果您多次重复同一组隐式参数,那么惯用的解决方案是引入您的类型 class(或只是单个隐式)而不是那组隐式并使用此类型 class .
不是惯用的解决方案是引入将为方法生成隐式参数部分的宏注释。
有时您可以将隐式传输到更高的某个级别
class MyClass(implicit val ec: ExecutionContext) extends ExecutionContextAware {
def f(x: String) = ???
def g(y: String) = f("xxx" + y)
}
trait ExecutionContextAware {
implicit def ec: ExecutionContext
}
或
trait MyTrait extends ExecutionContextAware {
def f(x: String) = ???
def g(y: String) = f("xxx" + y)
}
object Impl extends ExecutionContextAware {
implicit def ec: ExecutionContext = ExecutionContext.Implicits.global
}
trait ExecutionContextAware {
implicit def ec: ExecutionContext
}
Could you please also give an example with typeclass?
假设你有多个类型 classes
trait TC1[A] {
def foo = ???
}
trait TC2[A] {
def bar = ???
}
你必须在方法中重复它们
def f[A](implicit tc1: TC1[A], tc2: TC2[A]) = ???
1.然后可以介绍一下你的类型class
trait TC[A] {
def foo
def bar
}
通过TC1
、TC2
、...
object TC {
implicit def mkTC[A](implicit tc1: TC1[A], tc2: TC2[A]): TC[A] = new TC[A] {
def foo = tc1.foo
def bar = tc2.bar
}
}
并使用它
def f[A](implicit tc: TC[A]) = ???
2. 替代方法是
trait TC[A] {
implicit def tc1: TC1[A]
implicit def tc2: TC2[A]
}
object TC {
implicit def mkTC[A](implicit _tc1: TC1[A], _tc2: TC2[A]): TC[A] = new TC[A] {
implicit def tc1: TC1[A] = _tc1
implicit def tc2: TC2[A] = _tc2
}
}
def f[A](implicit tc: TC[A]) = {
import tc._
???
}
在您使用 ExecutionContextExecutor
、ActorMaterializer
的示例中(例如按照第二种方法),您可以引入
trait MyImplicit {
implicit def dispatcher: ExecutionContextExecutor
implicit def mat: ActorMaterializer
}
并替换
def f(x: String)(implicit dispatcher: ExecutionContextExecutor, mat: ActorMaterializer) = ???
和
def f(x: String)(implicit mi: MyImplicit) = {
import mi._
???
}