如何在swift中创建自定义运算符(例如〜=运算符)? —🤓🤓🤓🤓

我正在快速学习模式匹配,但是我的眼睛被一个特殊的运算符~=困住了。 我以前曾使用它进行模式匹配,但是我不知道它是如何工作的。 我已经使用~=运算符来检查http错误是否落入给定范围内的任何内容( 想要检查错误是否为4xx,不包括401 ),如下所示:

我不知道它在内部做什么。 我也不知道我们也可以像这样创建自定义运算符。 所以,我问谷歌这件事,他向我展示了我想要的一切。

快速查看一些此类运算符: 定义Swift

迅速的操作员分为以下几种类型:

  • -在两个值之间使用(例如: + )
  • 前缀 —在值之前使用(例如:!)
  • 后缀 -在值后使用(例如:!)
  • 三元数—在三个值之间插入两个符号(例如:?:)。 到目前为止,我们无法创建自定义三元运算符。 Swift不允许开发人员执行此操作。

让我们创建一个自定义运算符,以便使用符号查找数字的平方根。

注意: 我们已经有了 sqrt() 函数来查找平方根,并且易于使用。 将其视为创建自定义运算符 simple 的简单示例

我们应该将其用作前缀运算符,例如:

 让someVal = 25let squareRoot =√someVal //结果为5 
  • 我们需要将符号声明为前缀运算符。
 前缀运算符√ 
  • 我们需要创建一个接受一个参数并执行操作(平方根)的函数。
 前缀func√(lhs:Double)-> Double {return sqrt(lhs)} 

完成了! – – – 恭喜!!。 您刚刚创建了一个自定义前缀运算符来查找平方根。


◉运算符函数将接受两个值lhsrhs并返回这些值的平方和。 即 如果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上与我联系 推特

如果您有任何评论,问题或建议,请随时在下面的评论部分中发布它们!

Interesting Posts