F#使用System.Random生成随机ID出现重复值的问题如何解决?
F# 随机ID重复问题解答
猜测验证
你的猜测不正确。模块级别的let r = System.Random()绑定只会在模块初始化时执行一次,全程只会生成一个System.Random实例,不会每次调用都返回新实例。
重复ID根因
你当前的代码存在两个问题:
- 示例代码存在笔误:Test模块内定义的是参数为
create的函数t,但你后续调用的是不存在的Test.create,属于命名不匹配。 - 核心问题:你将创建记录的逻辑定义为了值绑定而非函数绑定,所以它只会在模块初始化阶段计算一次,生成固定的记录值,后续所有访问操作拿到的都是同一个预计算好的记录对象,自然id完全相同。
解决方案
将创建记录的逻辑定义为带单位参数()的函数,这样每次主动调用时才会执行代码,生成新的随机ID。
修正后可运行代码
[<AutoOpen>] module Domain = type Test = {id: int; (* 其他字段 *)} module Test = // 模块初始化时仅创建一次Random实例,复用避免重复 let private r = System.Random() // 定义为带单位参数的函数,每次调用才触发计算生成新记录 let create () = {id = r.Next(); (* 其他字段赋值 *)} // 每次主动调用create()都会生成全新的记录 let a = Test.create() let b = Test.create()
多线程场景补充
如果你的代码运行在多线程环境下,需要注意System.Random本身不是线程安全的,多线程并发调用Next()可能会返回异常或者重复值,这种场景下可以给Next()的调用逻辑加锁,或者为每个线程单独维护Random实例。
内容的提问来源于stack exchange,提问作者WilliamG
相关产品推荐
相关产品推荐

