如何在swift中创建自定义运算符(例如〜=运算符)? —🤓🤓🤓🤓
我正在快速学习模式匹配,但是我的眼睛被一个特殊的运算符~=
困住了。 我以前曾使用它进行模式匹配,但是我不知道它是如何工作的。 我已经使用~=
运算符来检查http
错误是否落入给定范围内的任何内容( 想要检查错误是否为4xx,不包括401 ),如下所示:
我不知道它在内部做什么。 我也不知道我们也可以像这样创建自定义运算符。 所以,我问谷歌这件事,他向我展示了我想要的一切。
快速查看一些此类运算符: 定义Swift
迅速的操作员分为以下几种类型:
- 缀 -在两个值之间使用(例如: + )
- 前缀 —在值之前使用(例如:!)
- 后缀 -在值后使用(例如:!)
- 三元数—在三个值之间插入两个符号(例如:?:)。 到目前为止,我们无法创建自定义三元运算符。 Swift不允许开发人员执行此操作。
让我们创建一个自定义运算符,以便使用√
符号查找数字的平方根。
注意: 我们已经有了 sqrt()
函数来查找平方根,并且易于使用。 将其视为创建自定义运算符 simple 的简单示例 。
我们应该将其用作前缀运算符,例如:
让someVal = 25let squareRoot =√someVal //结果为5
- 我们需要将符号
√
声明为前缀运算符。
前缀运算符√
- 我们需要创建一个接受一个参数并执行操作(平方根)的函数。
前缀func√(lhs:Double)-> Double {return sqrt(lhs)}
完成了! – – – 恭喜!!。 您刚刚创建了一个自定义前缀运算符来查找平方根。
◉运算符函数将接受两个值lhs
和rhs
并返回这些值的平方和。 即 如果lhs是2而rhs是3,则结果将是4 + 9。 13
如果您记得这些步骤,
- 我们需要将此◉符号声明为中缀运算符。
中缀运算符◉
- 我们需要创建一个接受两个参数的函数并执行上述操作。
infix func◉(lhs:Double,rhs:Double)-> Double {返回lhs * lhs + rhs * rhs}
如果这样做,编译器会大喊大叫: error:MyPlayground.playground:14:1:error:func声明中不需要或不允许’infix’修饰符
因此,通过删除infix关键字来重写该函数。
func◉(lhs:Double,rhs:Double)-> Double {返回lhs * lhs + rhs * rhs}
恭喜。 您刚刚创建了一个自定义的中缀运算符。 可是等等。 是吗??
问题:是吗? 创建自定义运算符时,我们是否还需要考虑其他因素?
答案:是😱😱😱!!! ..几乎忘记了我们在学校学到的操作员优先级。
请参阅页面: 操作顺序,操作 员声明 。
在数学和大多数计算机语言中,乘法的优先级高于加法。 因此,表达式2 + 3×4被解释为具有值2 +(3×4)= 14,而不是(2 + 3)×4 =20。我们在创建自定义运算符时也必须考虑这一点。 运算符的优先级是重要的因素。
苹果文档链接在这里 。
运算符优先级使某些运算符具有更高的优先级; 首先应用这些运算符。
运算符关联性定义了如何将具有相同优先级的运算符组合在一起-从左侧分组还是从右侧分组。 可以将其理解为“它们与左侧的表达式关联”或“它们与右侧的表达式关联”。
解析具有左关联性的类型,以便v1 + v2 + v3 == (v1 + v2) + v3
。 正确的关联性则相反。
如果在不指定优先级组的情况下声明新运算符,则它是
DefaultPrecedence
优先级组的成员。DefaultPrecedence
没有关联性,并且优先级比TernaryPrecedence
。
请参阅Apple文档,以快速获取使用的运算符的完整列表及其详细信息。
回到我们的infix运算符,它不适合任何标准优先级组。 我们将不得不创建自己的。 怎么做?
- 创建一个名为
SquareSumOperatorPrecedence
的优先级组。
优先组SquareSumOperatorPrecedence {lowerThan:MultiplicationPrecedencehigherThan:AdditionPrecedenceassociativity:leftassignment:false}
在这里,我们创建了一个优先级组,其优先级高于AdditionPrecedence且低于MultiplicationPrecedence并具有左关联性。
“ none”,“ left”或“ right”是关联性的可能值。
assignment
修饰符的工作方式如下:标记为assignment
符的运算符被折叠到一个可选的链中,从而允许foo?.bar += 2
可以作为foo?(.bar += 2)
来工作,而不必像(foo?.bar) += 2
。此行为将传递给
assignment: true
在优先级组上为assignment: true
。
- 现在,将您对your运算符的原始声明替换为以下内容:
中缀运算符◉:SquareSumOperatorPrecedence
而已。
而已。 !
- 了解操作符重载。类和结构可以提供它们自己的现有操作符实现。 这称为使现有操作员超负荷 。 例如:==,+等。
- 了解有关向自定义运算符添加通用类型约束的更多信息
请享用!!
如果您喜欢阅读这篇文章,请分享并给予鼓掌,以便其他人可以找到它!
您可以在Medium上关注我以获取新文章。 另外,在LinkedIn上与我联系 和 推特
如果您有任何评论,问题或建议,请随时在下面的评论部分中发布它们!