Scalacheck 总是为任意的 List[UUID] 生成相同的 UUID

Scalacheck always generates the same UUID for an arbitrary of List[UUID]

我正在尝试使用 scalacheck(版本 1.12.2)生成任意 UUID 的列表。由于某种原因,生成列表中的每个 UUID 都是相同的。对于其他类型,例如 List[String] 或 List[Int],情况并非如此。这是我写的代码:

import org.scalacheck.Arbitrary.arbitrary
import org.scalacheck.Arbitrary
import java.util.UUID

case class SomeUUIDClass(field: List[UUID])
case class SomeOtherClass(field: List[Int])

object Arb {
    implicit def arbUUID: Arbitrary[UUID] = Arbitrary {
        UUID.randomUUID()
    }

    implicit def arbUUIDClass = Arbitrary {
        for {
            field <- arbitrary[List[UUID]]
        } yield SomeUUIDClass(field)
    }

    implicit def arbOtherClass = Arbitrary {
        for {
            field <- arbitrary[List[Int]]
        } yield SomeOtherClass(field)
    }

    def main(args: Array[String]) {
        println("without uuids:")
        arbitrary[SomeOtherClass].sample.get.field.foreach(println(_))
        println("")

        println("with uuids:")
        arbitrary[SomeUUIDClass].sample.get.field.foreach(println(_))
    }
}

和一个示例 运行:

without uuids:
-1
0
2147483647
-1
-2147483648
527079214
-698179980
1192016877
-1001957700
0
682853458
-1
-2147483648
109314552
1130736291
1080418
1771214863
1164874892
-1306566270
2147483647
-2009106057
2147483647
-2147483648
-1
-1
-1
945958506
777623735
-490377345
-272177229
0
-2147483648
-1753697474
-1
736327057
415072340
0

with uuids:
a49540b4-29ce-464f-946d-3649f38fb8a6
a49540b4-29ce-464f-946d-3649f38fb8a6
a49540b4-29ce-464f-946d-3649f38fb8a6
a49540b4-29ce-464f-946d-3649f38fb8a6
a49540b4-29ce-464f-946d-3649f38fb8a6
a49540b4-29ce-464f-946d-3649f38fb8a6
a49540b4-29ce-464f-946d-3649f38fb8a6
a49540b4-29ce-464f-946d-3649f38fb8a6
a49540b4-29ce-464f-946d-3649f38fb8a6

使用 Gen.wrap() 应该可以。

因此,在您的示例代码中第一个隐含的地方,您可以将其更改为:

import org.scalacheck.Gen

implicit def arbUUID: Arbitrary[UUID] = Arbitrary {
  Gen.wrap(UUID.randomUUID) 
}

更新: 从版本 1.13.0 开始,wrap 已弃用,您可以使用 Gen.delay 代替:

import org.scalacheck.Gen

implicit def arbUUID: Arbitrary[UUID] = Arbitrary {
  Gen.delay(UUID.randomUUID) 
}

Scalacheck 版本 1.13.0 开始,您可以简单地使用 Gen.uuid:

import org.scalacheck.{Arbitrary, Gen}

implicit def arbUUID: Arbitrary[UUID] = Arbitrary {
        Gen.uuid
    }