我的代码大部分是从Scala 3书借来的
object Logarithms:
//vvvvvv this is the important difference!
opaque type Logarithm = Double
object Logarithm:
def apply(d: Double): Logarithm = math.log(d)
extension (x: Logarithm)
def toDouble: Double = math.exp(x)
def + (y: Logarithm): Logarithm = x + math.log1p(math.exp(y-x))
def * (y: Logarithm): Logarithm = x + y
// vvvvvvvvv these two do not work!
def toString: String = x.asInstanceOf[Logarithm].toDouble.toString
def toString2: String = x.asInstanceOf[Logarithm].toDouble.toString
//def toString: String = x.toDouble.toString // does not work either问题是我无法使toString工作,它不能从内部表示转换值:
$ ~/Downloads/scala3-3.1.3/bin/scala
Welcome to Scala 3.1.3 (14.0.1, Java OpenJDK 64-Bit Server VM).
scala> import Logarithms.*
scala> Logarithm(4)
val res0: Logarithms.Logarithm = 1.3862943611198906 <<== the internal representation
scala> Logarithm(4).toDouble
val res1: Double = 4.0 <<== as expected
scala> Logarithm(4).toDouble.toString
val res2: String = 4.0 <<== as expected
scala> Logarithm(4).toString
val res3: String = 1.3862943611198906 <<== expected: 4.0 !!!
scala> Logarithm(4).toString2
val res4: String = 1.3862943611198906 <<== expected: 4.0 !!!如何在不复制toDouble 中的代码的情况下定义toString
UPD
def toString: String = "log:"+x.asInstanceOf[Logarithm].toDouble.toString
def toString2: String = "log:"+x.asInstanceOf[Logarithm].toDouble.toString我得到了
scala> Logarithm(4).toString
val res0: String = 1.3862943611198906 <<== expected: log:4.0
scala> Logarithm(4).toString2
val res1: String = log:1.3862943611198906 <<== expected: log:4.0发布于 2022-08-26 14:06:13
关于你问题的那一部分
如何在不复制toString代码的情况下定义
toDouble?
只是不要叫它"toDouble“。在已知不透明类型为Double的上下文中,toDouble方法将被解释为只是通常的Double#toDouble (即它什么也不做)。如果您将toDouble重命名为类似于toLinear的东西(在toString2内部使用),那么toLinear将不会与内置的toDouble发生冲突,您的toString2将按预期工作:
opaque type Logarithm = Double
object Logarithm:
def apply(d: Double): Logarithm = math.log(d)
extension (x: Logarithm)
private def toLinear: Double = math.exp(x)
def toDouble: Double = toLinear
def toString2: String = s"Logarithm(${x.toLinear.toString})"
println(Logarithm(4.0).toString2) // Logarithm(4.0)但是,您不能对toString做任何事情,因为toString是在AnyRef / java.lang.Object上定义的,而您只是无法摆脱它。您可以尝试使用Show类型,这取决于它是否适合您的项目。
https://stackoverflow.com/questions/73493887
复制相似问题