请记住,我一周前开始使用Scala。
课程: 货币-抽象,比特币,美元,欧元
特质: 转换器,打印机
我的抽象类有2个变量: Name 和 Value (均为变量)
转换器特性中的方法
def convert(to:Currency):Double = ???
这是我卡住的部分。我需要在每个子类(货币)中重写此方法,以便它们从一种货币转换为另一种货币。我可以用新方法来做,但是需要用一种方法来做。我应该将什么作为参数传递,以便该方法识别将其转换为哪个参数。 欧元,美元和比特币仅采用一个整数作为参数。
我也不理解参数的“ to:”部分。
由于这也是我关于Stack Overflow的第一个问题,我不太确定这是如何工作的,我想指出,我很期待指针和/或建议,因为简单的解决方案不会从长远来看对我有帮助。如果你们中的某些人认为我遗漏了一些重要信息,请随时告诉我,我会很乐意编辑我的问题。
答案 0 :(得分:1)
to: Currency
表示您正在声明一个名为to
的参数,其类型为Currency
。不幸的是,您不希望使用Currency对象,因为其中包含特定金额-您只想将应该返回的货币类传递给它。
好吧,你可以这样:
def convert(to: Class[Currency]): Double = ???
但是类型安全性更高的方法是这样做:
def convert[C <: Currency](to: Class[C]): C = ???
但是我不确定您将如何实现这一目标。您可能需要为此使用Manifest
而不是Class
。
答案 1 :(得分:0)
欢迎使用 StackOverflow 。
首先,作为对以后问题的建议,请尝试提供所有可以的(相关)代码-例如,在这种情况下,并发类的定义将很有用。
第二,我相信这是一项任务,可能您不需要走得太远。
正如Robin所说的那样,此to
参数用于确定目标类型-但由于它将是一个类,因此它将具有一个值,这是不希望的。
我想这个想法是传递一个空类,然后使用 pattern matching 进行类似的操作。
class Bitcoin(override val amount: Int = 0) extends Concurrency(amount) {
override def convert(to: Concurrency): Concurrency = to match {
case _: Bitcoin => this // no need to transform
case _: Euro => new Euro((this.amount / 2).toInt)
case _: Dollar => new Dollar((this.amount / 3).toInt)
}
}
new Bitcoin(30).convert(to = new Dollar()) // res0: Concurrency: Dollar(10)
第三,这是一个类型安全性更高的解决方案,希望您能找到有趣且“有趣” (部分)-故意开玩笑。
sealed abstract class Concurrency(val amount: Int) {
def name: String
/** Tansforms this concurrency value to a new target type. */
final def to[C <: Concurrency](implicit builder: Concurrency.Builder[C]): C =
builder.build(this)
}
object Concurrency {
/** Builder of target concurrencies. */
trait Builder[C <: Concurrency] {
def build(origin: Concurrency): C
}
}
final case class Bitcoin(override val amount: Int) extends Concurrency(amount) {
override final val name: String = "Bitcoin"
}
object Bitcoin {
import Concurrency.Builder
implicit val BitcoinBuilder: Builder[Bitcoin] = new Builder[Bitcoin] {
override def build(origin: Concurrency): Bitcoin = origin match {
case b: Bitcoin => b // no need to transform
case Euro(amount) => Bitcoin(amount * 2)
case Dollar(amount) => Bitcoin(amount * 3)
}
}
}
final case class Euro(override val amount: Int) extends Concurrency(amount) {
override final val name: String = "Euro"
}
object Euro {
import Concurrency.Builder
implicit val EuroBuilder: Builder[Euro] = new Builder[Euro] {
override def build(origin: Concurrency): Euro = origin match {
case e: Euro => e // no need to transform
case Bitcoin(amount) => Euro((amount / 2).toInt)
case Dollar(amount) => Euro((amount / 1.5).toInt)
}
}
}
final case class Dollar(override val amount: Int) extends Concurrency(amount) {
override final val name: String = "Dollar"
}
object Dollar {
import Concurrency.Builder
implicit val DollarBuilder: Builder[Dollar] = new Builder[Dollar] {
override def build(origin: Concurrency): Dollar = origin match {
case d: Dollar => d // no need to transform
case Euro(amount) => Dollar((amount * 1.5).toInt)
case Bitcoin(amount) => Dollar((amount / 3).toInt)
}
}
}
Dollar(10).to[Bitcoin] // res0: Bitcoin = Bitcoin(30)
毫无疑问地要求澄清。