使用callv调用randf_range始终返回上限值的原因
GDScript中
callv调用randf_range始终返回上限值的原因 GDScript里的Callable类型提供了callv方法,它的作用是调用Callable指向的方法,和call()不同的是,callv要求所有参数都放在一个数组里传入。
我尝试把randf_range的参数定义成常量简化调用,原本的写法是:
rng.randf_range(0.1, 0.3)
改成了:
const RANGE = [ .1, .3 ] rng.randf_range.callv(RANGE)
但运行后每次都返回上限值0.3,以下是最小复现代码:
const RANGE = [ .1, .3 ] var rng = RandomNumberGenerator.new() rng.seed = hash("HuH") for i in range(3): print('%d -> %f' % [ i, rng.randf_range.callv(RANGE) ]) rng = RandomNumberGenerator.new() rng.seed = hash("HuH") for i in range(3): print('%d -> %f' % [ i, rng.randf_range(RANGE[0], RANGE[1]) ])
输出结果:
0 -> 0.300000 1 -> 0.300000 2 -> 0.300000 0 -> 0.214059 1 -> 0.191159 2 -> 0.203312
原因分析
问题出在callv的参数传递逻辑上:
当你通过rng.randf_range获取Callable时,这个Callable已经自动绑定了rng实例作为方法的self参数。而callv传入的数组会作为额外参数追加到这个绑定参数之后。
也就是说,rng.randf_range.callv([.1, .3])实际等价于调用randf_range(rng, .1, .3),但randf_range的正确参数签名是randf_range(min: float, max: float)——这里错误地把rng实例当成了min参数,.1当成了max参数。由于对象实例的哈希值远大于0.3,触发了方法的边界逻辑:当min >= max时,直接返回max值,所以你看到的结果始终是0.3。
正确写法
有两种简单的解决方式:
- 使用数组展开操作符
*,直接把数组拆成单个参数传入:
const RANGE = [ .1, .3 ] rng.randf_range(*RANGE)
这种写法和直接写rng.randf_range(RANGE[0], RANGE[1])效果完全一致,代码更简洁。
- 获取未绑定的Callable,再通过
callv传入实例和参数:
const RANGE = [ .1, .3 ] RandomNumberGenerator.randf_range.callv([rng] + RANGE)
内容的提问来源于stack exchange,提问作者0stone0
相关产品推荐
相关产品推荐

