Scala - List.isDefinedAt()表现得很奇怪

时间:2012-06-01 12:46:32

标签: list scala

据我所知,isDefinedAt方法应该像类型contains方法一样工作。但奇怪的是,它的行为有所不同 - 它不会检查重复出现的元素。

val randomizer = new Random

def next(acc: List[Int], n: Int): List[Int] = {
   if(n > 0) {
      val r = randomizer.nextInt(15)
      println("generating, r=" + r + " is defined=" + acc.isDefinedAt(r))
      if(!acc.isDefinedAt(r)) next(r :: acc, n - 1) // check for NO coincidence
      else next(acc, n)
   } else acc
}

println("indices = " + next(List[Int](), 6))

当然,我可以使用套装而不是列表,但是,为什么它会像这样呢?

我得到的输出就像

generating, r=8 is defined=false
generating, r=13 is defined=false
generating, r=2 is defined=false
generating, r=8 is defined=false
generating, r=9 is defined=false
generating, r=3 is defined=true
generating, r=2 is defined=true
generating, r=7 is defined=false

indices = List(7, 9, 8, 2, 13, 8)

3 个答案:

答案 0 :(得分:7)

isDefineAt方法告诉你是否为给定的参数定义了一个给定的部分函数,​​即当你用给定的参数调用它时它是否会给你一个值。

由于列表被视为从索引到其值的部分函数,​​isDefinedAt将告诉您给定索引是否对List有效。它不会告诉您列表中是否包含给定值,这是contains的用途。

请注意,尽管您调用了列表indices,但该列表中的是7,9,8,2,13和8。该列表的索引是0,1,2,3,4和5.

答案 1 :(得分:5)

你误解了isDefindAt的意思,它不是contains。 正如文档所说:

  

def isDefinedAt(x:Int):Boolean

     

测试此列表是否包含给定索引。

     

返回

true if this list contains an element at position idx, false otherwise.

因此isDefinedAt(x)等于0<= x && x< list.size

答案 2 :(得分:3)

所有isDefinedAt都会告诉您函数是否不接受参数。也就是说,如果isDefinedAt返回false,那么您就知道该函数未涵盖该值。对于true,它可能会覆盖该值或抛出异常。

List(以及所有Seq)的特定情况下,如果isDefinedAt(i),则0 <= i < list.size将返回true,否则将返回false,list(i)将仅返回isDefinedAt(i)如果scala> val list = List("a", "b", "c") list: List[String] = List(a, b, c) scala> list.isDefinedAt(0) res0: Boolean = true scala> list(0) res1: String = a scala> list.isDefinedAt(-1) res3: Boolean = false scala> list(-1) java.lang.IndexOutOfBoundsException: -1 scala> list.isDefinedAt(2) res5: Boolean = true scala> list(2) res6: String = c 返回false,则抛出异常。

无论如何,让我们尝试一下:

{{1}}