Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/scala/18.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在列表中使用自定义scala类型_Scala_Custom Type_Typelist - Fatal编程技术网

在列表中使用自定义scala类型

在列表中使用自定义scala类型,scala,custom-type,typelist,Scala,Custom Type,Typelist,我希望创建一个表示数据大小(字节、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

我希望创建一个表示数据大小(字节、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)
  }  
}
def convertTo(目标类型:SizeUnit):SizeUnit={ def电源(itr:Int):Int={ 如果(itr==0)1 else 1024*功率(itr-1) } val距离=size.indexOf(targetType)-size.indexOf(this) 距离赛{ //相同类型-相同值 案例0=>targetType //正距离表示较大的单位-较小的数字 案例x>0=>targetType/power(距离) //负距离意味着更小的单位-更大的数字,并注意负性 案例x目标类型*功率(距离)*(-1) } } 在检查该方法的有效性之前,我遇到了一些问题(因为我是Scala新手):

  • 有没有办法创建一个保存类型而不是值的列表(或任何其他Seq)?或者更确切地说-类型作为值
  • 如果我理解正确,类型不会超出编译范围。这是否意味着在运行时,如果我将一个GB值传递给现有的KB,它就无法破译类型
谢谢,,
Ehud类型不是Scala中的值


您可能应该查看您的用例。

所有这些类型都只是类型别名,而不是独立的类型

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, Int, Int, Int, Int, Int, Int)
同样,您永远不能使用这些类型来编写接受MB数量所需的函数,因为所有这些类型都是相同的

要将B、KB、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
KB
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, KB, 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)
}

这样,一旦你导入了隐式,你就可以简单地编写
4MB
123456789b
而不是
Storage(4MB)
Storage(123456789,B)

这些都是好主意,但它们并不能解决我的主要问题,即如何在不硬编码每个人所需电源的情况下进行转换,例如def toB(storage:storage)storage.unit match{case KB=>storage.num*1024….@EhudKaldor如果
B
KB
MB
,等等是对象,而不是类型,你可以对它们做任何事情。例如,你可以构造列表
列表(B,KB,MB…)
,并有一个函数
转换(数量:存储,单位:SizeUnit):使用两个
SizeUnit
值列表中的位置来计算它们之间的比率的存储。