在Scala中,如何避免强制转换函数参数?

格雷格

我希望组件具有各种“风味”,每个风味都处理不同的“接线”格式(例如,字符串,字节数组等)。下面的例子。read()函数的内在并不重要。

请注意,在使用我需要投参数"Heavy"thing.WIRE工作。由于这是我的顶级API,因此我不希望用户强制转换。他们在致电时已选择口味FantasticThing.apply(或接受默认值)。在那之后,我宁愿不需要演员。

如何避免强制转换并使Scala意识到read()参数是基于被选择字符串StringFlavor

trait Flavor {
  type WIRE
  def read[T](wire: WIRE)(implicit tt: TypeTag[T]): T
}

trait Maker {
  def make(): Flavor
}

object StringFlavor extends Maker {
  def make(): Flavor { type WIRE = String } = StringFlavor()
}

case class StringFlavor() extends Flavor {
  type WIRE = String
  def read[T](wire: String)(implicit tt: TypeTag[T]): T = {
    println(tt.tpe)
    if(tt.tpe =:= typeOf[Int]) {
      5.asInstanceOf[T]
    } else
      throw new Exception("Boom")
  }
}

object FantasticThing {
  def apply[WIRE](maker: Maker = StringFlavor): Flavor = maker.make()
}

object RunMe extends App {
  val thing: Flavor = FantasticThing(StringMaker)
  println(thing.read[Int]("Heavy".asInstanceOf[thing.WIRE])) // <-- How can I avoid this cast?
}
  • 根据Luis Miguel的注释进行编辑:我无法真正将该类型添加到FantasticThing.apply()中,否则将失去可插入性。我希望用户轻松选择他们想要的口味。我已经进行了一些重构,以工厂模式展示了这一点,该工厂模式确实添加了您建议的类型信息,但是不幸的是,仍然需要我进行顶级转换。

如果我提供了一堆调味料,那么用户应该可以执行以下操作:

val foo = FantasticThing(ByteArrayFlavor)
古斯塔德

您可以创建WIRE类型参数,并通过类型成员或您的Maker类型传播它即:

import scala.reflect.runtime.universe._

trait Flavor[WIRE] {
  def read[T](wire: WIRE)(implicit tt: TypeTag[T]): T
}

trait Maker {
  type O
  def make(): Flavor[O]
}

object StringMaker extends Maker {
  type O = String
  def make(): Flavor[O] = StringFlavor()
}

case class StringFlavor() extends Flavor[String] {
  def read[T](wire: String)(implicit tt: TypeTag[T]): T = {
    if(tt.tpe =:= typeOf[Int]) {
      5.asInstanceOf[T]
    } else
      throw new Exception("Boom")
  }
}

object FantasticThing {
  def apply(): Flavor[String] = StringMaker.make()
  def apply(maker: Maker): Flavor[maker.O]  = maker.make() // Path dependent type.
}

object RunMe extends App {
  val thing: Flavor[String] = FantasticThing(StringMaker)
  thing.read[Int]("Heavy") // res0: Int = 5
}

编辑:向此anwser添加了无参数的apply()。如果使用maker的默认值(例如StringMaker),则会出现编译错误,因为参数“ Heavy”现在应该为Maker.O类型。添加无参数应用程序可以解决此问题,同时为调用者​​提供相同的体验。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

如何避免强制转换和instanceOf

带界面的工厂模式,如何避免强制转换

如何读取文件并避免强制转换为python中的unicode错误?

如何使用fgets()避免强制转换其类型为int的第二个参数?

java接口避免强制转换

键入DefaultListModel以避免强制转换

如何在子视图控制器中避免强制类型转换视图模型实例-MVVM

如何避免强制展开变量?

如何在函数参数中强制执行类型并避免隐式转换?

与HKT模式匹配-避免强制转换返回类型

避免强制转换operator()和access operator []冲突

如何在Material主题中避免强制暗模式?

读取空值时如何避免强制关闭

避免强制回调

需要说明:通用的友好性以避免强制转换,Java 8中不再需要此功能

如何防止构造函数在C ++中强制转换参数类型?

如何从元组强制转换函数参数?

Objective-C:是否有任何技巧可以避免强制转换NSArray对象?

使用 C++ 类型特征,是否有某种方法可以避免强制转换

可以使用更好的类型定义来避免强制转换为 any 吗?

scala - 如何避免使用可变列表和强制转换

如果没有要在db中提取的数据,如何避免强制关闭

如何在Scala中强制转换变量?

如何避免在函数中传递“冗余”参数?

如何从不带参数的Java中的静态泛型函数强制转换?

如何避免在java中的子类中进行强制转换

在C#中强制转换泛型函数类型参数

在函数参数中强制转换数据类型?

如何强制强制转换类型的字典以避免分配中的不兼容类型