编译时检查某些属性 [英] Compile time check on some property

查看:40
本文介绍了编译时检查某些属性的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

给定以下 Scala 代码:

Given the following scala code:

sealed trait Color
case object Red extends Color
case object Blue extends Color

sealed trait Car {
  def isBroken: Boolean
  def color: Color
}

如何定义这样的方法:

def fixBrokenRedCar(c: A): B

也就是说,AB 应该是什么?该方法应该只接受 RedisBroken = true 的 Car.否则它应该发出编译错误.此外,输出 B 应该包含有关其类型的信息,这样如果我创建另一个方法 destroyRedCar(c: B) 并将其应用于输出,它应该相应地编译.

That is, what should A and B be? The method should only accept a Car that is both Red and isBroken = true. Otherwise it should emit a compile error. Moreover, the output B should contain information on its type such that if I create another method destroyRedCar(c: B) and apply it on the output, it should compile accordingly.

推荐答案

你应该将你的数据移动到类型级别然后:

You should move your data to the type-level then:

trait Bool
trait T extends Bool
trait F extends Bool

trait Color
trait Red extends Color
trait Blue extends Color

trait Car[Clr <: Color, Brkn <: Bool]

def fixBrokenCar[Cr <: Car[Red, T]](c: Cr) = new Car[Red, F]{}

scala> fixBrokenCar(new Car[Blue, T]{})
<console>:16: error: inferred type arguments [Car[Blue,T]] do not conform to method fixBrokenCar's type parameter bounds [Cr <: Car[Red,T]]
              fixBrokenCar(new Car[Blue, T]{})
              ^
<console>:16: error: type mismatch;
 found   : Car[Blue,T]
 required: Cr
              fixBrokenCar(new Car[Blue, T]{})
                           ^

scala> fixBrokenCar(new Car[Red, T]{})
res3: Car[Red,F] = $anon$1@67d9a642

摧毁"它:

def destroyRedCar(c: Car[Red, _]) = true

scala> destroyRedCar(fixBrokenCar(new Car[Red, T]{}))
res10: Boolean = true

scala> destroyRedCar(new Car[Red, T]{})
res11: Boolean = true

scala> destroyRedCar(new Car[Blue, T]{})
<console>:15: error: type mismatch;
 found   : Car[Blue,T]
 required: Car[Red, ?]
              destroyRedCar(new Car[Blue, T]{})
                            ^

如果您需要变异"Cr 类型(从另一种类型构造一种类型,更准确地说):

If you need to "mutate" Cr type (construct one type from another, more precisely):

trait Car[Clr <: Color, Brkn <: Bool] { 
   type Copy[C <: Color, B <: Bool] <: Car[C,B] // define "copy" type-method
}

trait BrandedCar[Clr <: Color, Brkn <: Bool] extends Car[Clr, Brkn] {
   type Copy[C <: Color, B <: Bool] = BrandedCar[C, B] // implement "copy" type-method
   def brand: String = "default"
}

def fixBrokenCar[Cr <: Car[Red, T]](c: Cr) = c.asInstanceOf[Cr#Copy[Red, F]]

def checkBrandedCar(c: BrandedCar[_, F]) = true // accepts only branded and fixed


scala> checkBrandedCar(new BrandedCar[Red, F]{})
res10: Boolean = true

scala> checkBrandedCar(new Car[Red, F]{})
<console>:15: error: type mismatch;
 found   : Car[Red,F]
 required: BrandedCar[?, F]
              checkBrandedCar(new Car[Red, F]{})
                              ^

scala> checkBrandedCar(fixBrokenCar(new BrandedCar[Red, T]{}))
res12: Boolean = true

你也可以在 Car 的 trait 中定义一些 def copy[C <: Color, B <: Bool]: Copy[C, B] 方法(就像在 case 类中)而不仅仅是 asInstanceOf.

You may also define some def copy[C <: Color, B <: Bool]: Copy[C, B] method inside Car's trait (like in case classes) instead of just asInstanceOf.

这篇关于编译时检查某些属性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆