防止 Scala 特征成为 SAM 类型
Prevent a Scala trait from qualifying as a SAM type
我有一个trait Modifier[-A] extends (A => Unit)
。
但是,Scala 2.12 magic SAM 语法会默默地将任何 lambda 文字(如 el => foo)转换为 Modifier,因为 Modifier 符合 SAM 类型(此语法的适用规则是 here)。
我不希望这种转换应用于我的修饰符特征,因为它会干扰我的库的语法。简而言之,我有一个从 A => Modifier[A]
到 Modifier[A]
的隐式转换。在 2.12 中,不会为 lambda 文字(例如 thisNode => someModifier(thisNode, otherParam)
)触发该转换,因为 Scala 将 A => Modifier[A]
lambda 本身魔术化为 Modifier[A]
,而不是正确的。
我知道有几种方法可以解决这个问题:
1) 修饰符特征不应该扩展 Function1,而是应该定义自己的抽象 def apply[X](element: El): Unit
方法。由于幻像类型参数 X,未应用 SAM 语法。
2) 给Modifier trait添加一个无意义的抽象protected[this] def foo
。这将使 SAM 语法不适用,如果我正确理解 Scala.js 死代码消除,这个伪造的方法将从运行时消除。
我倾向于选项 1,因为它似乎减轻了 Modifier 的实施者的负担,而且更明显的是它不会影响运行时性能。
但它仍然看起来很老套,而且我不喜欢无用的幻影类型会泄漏到我的库的 API 中。有没有更好的办法?
感谢任何建议。
正如您从 Scala 2.12 的文档中看到的那样Sam Conversions precedes implicits:该文档还讨论了覆盖此行为的潜在解决方案。
如果您需要自动进行转换,两种方法都是合理的:
如果您扩展自己的自定义 MyFunction1
您可能会失去标准库的组合优势
如果添加无意义的方法,一旦使用Function1
[=27上定义的方法执行组合操作,您将回退到标准Function1 =]
在您的情况下,我想这两种方法都可以,因为您的 Modifier apply
正在返回 Unit 并且您不会将这些操作通过管道或连接在一起。
我有一个trait Modifier[-A] extends (A => Unit)
。
但是,Scala 2.12 magic SAM 语法会默默地将任何 lambda 文字(如 el => foo)转换为 Modifier,因为 Modifier 符合 SAM 类型(此语法的适用规则是 here)。
我不希望这种转换应用于我的修饰符特征,因为它会干扰我的库的语法。简而言之,我有一个从 A => Modifier[A]
到 Modifier[A]
的隐式转换。在 2.12 中,不会为 lambda 文字(例如 thisNode => someModifier(thisNode, otherParam)
)触发该转换,因为 Scala 将 A => Modifier[A]
lambda 本身魔术化为 Modifier[A]
,而不是正确的。
我知道有几种方法可以解决这个问题:
1) 修饰符特征不应该扩展 Function1,而是应该定义自己的抽象 def apply[X](element: El): Unit
方法。由于幻像类型参数 X,未应用 SAM 语法。
2) 给Modifier trait添加一个无意义的抽象protected[this] def foo
。这将使 SAM 语法不适用,如果我正确理解 Scala.js 死代码消除,这个伪造的方法将从运行时消除。
我倾向于选项 1,因为它似乎减轻了 Modifier 的实施者的负担,而且更明显的是它不会影响运行时性能。
但它仍然看起来很老套,而且我不喜欢无用的幻影类型会泄漏到我的库的 API 中。有没有更好的办法?
感谢任何建议。
正如您从 Scala 2.12 的文档中看到的那样Sam Conversions precedes implicits:该文档还讨论了覆盖此行为的潜在解决方案。
如果您需要自动进行转换,两种方法都是合理的:
如果您扩展自己的自定义
MyFunction1
您可能会失去标准库的组合优势如果添加无意义的方法,一旦使用
[=27上定义的方法执行组合操作,您将回退到标准Function1 =]Function1
在您的情况下,我想这两种方法都可以,因为您的 Modifier apply
正在返回 Unit 并且您不会将这些操作通过管道或连接在一起。