crystal-lang - Crystal Lang 中的“&-=”运算符是什么?
问题描述
我刚刚了解了&-=
Crystal 中的存在运算符。它有什么作用?
这是Mutex#try_lock的一个示例:
private def try_lock
i = 1000
while @state.swap(1) != 0
while @state.get != 0
Intrinsics.pause
i &-= 1
return false if i == 0
end
end
true
end
在尝试时,我看不出与熟悉的-=
操作员有什么不同。例如,这两个片段产生相同的输出:
i = 1000
while i != 0
puts i
i -= 1
end
i = 1000
while i != 0
puts i
i &-= 1
end
解决方案
难题的第一部分是意识到这a &-= b
只是a = a &- b
. 或者更一般地说a op= b
是语法糖a = a op b
。语言参考在Operators中的“Combined assignments”下对此进行了详细说明。
现在我们需要问它是什么&-
以及它有什么不同-
?不幸的是,API 文档在这方面写得很安静。语言参考也不是很详细,但在与上面相同的 Operators 页面上,我们可以找到:
-
减法
&-
换行减法
那么什么是换行减法呢?好吧,Crystal 有固定大小的数字类型。所以在这种情况下它们可能会溢出或下溢。这意味着什么?让我们举个例子:
# We have something to sell! Let's keep track of how many!
# It doesn't really make sense to have negative something left,
# so an unsigned integer ought to this.
items_left = 2u32
# Just made the first sell! Let's remember
items_left -= 1
# People seem to actually like this
items_left -= 1
# I could do this all day!
items_left -= 1 # => Unhandled exception: Arithmetic overflow (OverflowError)
# Oh no what happend?
所以程序试图去下面0
,UInt32
类型不能代表。它下溢。如果 Crystal 不做这个检查,CPU 会很高兴地环绕整数类型,我们会进入4294967295
( items_left
) UInt32::MAX
。
但有时,在低级代码中,这种行为是我们想要的。例如,如果我们正在计算一些统计数据,比如发送的数据包,如果该计数器上溢或下溢,我们不希望程序在这种情况下失败,环绕是可以的。或者也许我们有一些性能敏感的代码,并且确定它的行为正确并且永远不会溢出,所以我们不想在检查操作是否刚刚溢出时支付额外的 CPU 周期。
对于这些情况,有&
前缀数学运算符。他们只是执行操作而不进行任何溢出检查。如果我们在上面的示例中使用&-
而不是-
,我们现在就会4294967295
使用items_left
。
通常,您知道是否需要或从包装运算符中受益。有疑问,就假装它们不存在。
推荐阅读
- perl - 如何在不禁用严格的'refs'的情况下重命名perl __ANON__ sub?
- firefox - 如何在 Firefox 最新版本 81.0 中打开 Scratchpad
- php - how do i show an image in laravel with infyom crud generator
- html - 如何结合 Angular ngStyle 指令使用“repeat()”css 函数?
- python - Python XML 按属性/子项排序
- unity3d - Unity3d-如何检查我的角色是否在空中 2 秒?
- java - 意图/开始活动开始错误的活动?
- python - 如何在基于类的视图 django 中验证会话
- flutter - 使用 Riverpod Flutter 创建登录功能
- r - 在 Rstudio 的一个文件夹中获取多个文件