加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

scala – 模糊的隐含值是我们想要在编译时存在错误的唯一方法

发布时间:2020-12-16 18:43:02 所属栏目:安全 来源:网络整理
导读:trait Footrait Bar extends Foodef doStuff[T : Foo](x: T)(implicit ev: T =!:= Foo) = xdoStuff(new Foo{}) //ambiguous implicit valuedoStuff(new Bar)// successful 隐式解决方案正在编译时发生,所以在这里我认为可能有两个隐式值具有完全相同的类型来
trait Foo

trait Bar extends Foo

def doStuff[T <: Foo](x: T)(implicit ev: T =!:= Foo) = x

doStuff(new Foo{}) //ambiguous implicit value
doStuff(new Bar)// successful

隐式解决方案正在编译时发生,所以在这里我认为可能有两个隐式值具有完全相同的类型来触发模糊的东西.

现在,我将在团队中引入无形的,我的同事们认为这种含糊不清的暗示并不理想,我对此没有强烈的争论.这是唯一的方法,以便在scala中使类型安全.如果是,我该怎么做才能自定义错误消息?

编辑:

在无形状中,我想使2 NAT的总和不等于7,我可以像这样编码使编译失败.

def typeSafeSum[T <: Nat,W <: Nat,R <: Nat](x: T,y: W)
         (implicit sum: Sum.Aux[T,W,R],error: R =:!= _7) = x

typeSafeSum(_3,_4)

但错误信息是含糊不清的隐含值,如何自定义错误信息?

解决方法

一个简单的类型类比这个(以及大多数其他)实例中的类型不等式测试更好.

据推测,想要排除Foo的原因是Bar(和它的兄弟姐妹)有一些Foo缺乏的属性.如果是这种情况,那么你应该创建一个类型类来捕获这些属性,并对doStuff的类型参数提出要求.您可以使用Scala的@implicitNotFound批注,以便在不满足该要求时使编译器错误消息更易于理解.

@annotation.implicitNotFound(msg = "No Props instance for ${T}")
trait Props[T] {
  def wibble(t: T): Double
}

trait Foo
// Note no Props instance for Foo ...

trait Bar extends Foo
object Bar {
  // Props instance for Bar
  implicit def barProps: Props[Bar] = new Props[Bar] {
    def wibble(t: Bar): Double = 23.0
  }
}

def doStuff[T <: Foo](t: T)(implicit props: Props[T]) = props.wibble(t)

scala> doStuff(new Foo {})
<console>:11: error: No Props instance for Foo
              doStuff(new Foo {})
                     ^

scala> doStuff(new Bar {})
res1: Double = 23.0

如果没有任何这样的属性可以区分Foo和Bar,那么你应该质疑你的假设,你需要首先从doStuff中排除Foo.

如果您在项目中使用无形,我会很高兴,但您应该使用=!:=(和Scala自己的=:=)作为最后的手段,如果有的话.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读