在List中使用自定义scala类型
我期待创建一个表示数据大小(字节,KB …)的类型系列.为此,我们的想法是建立一个基本类型,使其具有以下实际尺寸:
type SizeUnit = Int type B = SizeUnit type KB = SizeUnit type MB = SizeUnit type GB = SizeUnit type TB = SizeUnit type PB = SizeUnit type EB = SizeUnit type ZB = SizeUnit type YB = SizeUnit 有一个有序的列表: val sizes = List(B,KB,MB,GB,TB,PB,EX,ZB,TB) 并且有一个转换方法,它采用目标类型,找到它们之间的索引差异,并乘以差异的幂乘以1024.所以: def convertTo(targetType: SizeUnit): SizeUnit ={ def power(itr: Int): Int = { if (itr == 0) 1 else 1024*power(itr-1) } val distance = sizes.indexOf(targetType) - sizes.indexOf(this) distance match { //same type - same value case 0 => targetType //positive distance means larget unit - smaller number case x>0 => targetType / power(distance) //negative distance means smaller unit - larger number and take care of negitivity case x<0 => targetType * power(distance) * (-1) } } 在我检查方法的有效性之前我有一些问题(因为我是Scala的新手): >有没有办法创建一个包含类型而不是值的List(或任何其他Seq)?或者更确切地说 – 类型作为值? 谢谢, 解决方法
所有这些类型都只是类型别名,而不是独立类型.
scala> type SizeUnit = Int defined type alias SizeUnit scala> type B = SizeUnit defined type alias B scala> type KB = SizeUnit defined type alias KB scala> (3 : KB) == (3 : B) res0: Boolean = true 类型别名只是同一类型的不同名称.所以即使你可以写它,你的列表也相当于写了: val sizes = List(Int,Int,Int) 同样地,您永远不能使用这些类型来编写接受MB数量所需的函数,因为所有这些类型都是相同的. 要将B,MB等分离为整数的不同“种类”,您需要将它们作为Int的子类型,而不是Int的类型别名.但Int是最终类型,因此无论如何都不能对其进行子类型化. 更好的方法是让Int表示原始数字,而是实现一个表示Int和一个单元的类型.你可以采取几种方法,但我会这样做: abstract class SizeUnit case object B extends SizeUnit case object KB extends SizeUnit case object MB extends SizeUnit case class Storage(num : Int,unit : SizeUnit) 现在3兆字节是存储(3,MB),17字节是存储(17,B).您可以在任意整数和存储数量之间进行静态强制分离,并且只要有存储数量,就始终将单元作为数据对象(无需静态推断).您可以将对象B,MB等放在一个列表中,并根据需要对它们进行任何操作. 或者,您可以使单元对象本身包含有关它们之间的顺序或比率的一些信息,而不是将该信息存储在外部列表中. 您甚至可以使用此方案通过隐式转换来处理古怪的事情.我想起这样的事情: object SizeableInt { // since I want to give the conversion methods the same name as the // units,I need different names to refer to the units in the // implementation of those methods. If B,etc were defined in // a different qualified namespace,this wouldn't be necessary. private val _B = B private val _KB = KB private val _MB = MB case class SizeableInt(x : Int) { def B : Storage = Storage(x,_B) def KB : Storage = Storage(x,_KB) def MB : Storage = Storage(x,_MB) } implicit def makeSizeableInt(x : Int) : SizeableInt = SizeableInt(x) } 有了它,一旦你导入隐式,你可以简单地写4 MB或123456789 B而不是存储(4,MB)或存储(123456789,B). (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |