重视我,每天共享一个关于 iOS 的新知识
前语
Swift 中的自界说运算符能够使代码更易于阅读和保护。必定程度上也能够让你编写更少的代码,同时保持逻辑明晰。
在 Swift 中开发代码时,咱们都经常运用默许运算符,比如运用 + 符号将两个数字相加,或许将两个字符串相加。今天来聊聊自界说运算符。
重载运算符
运算符重载允许在自界说类或结构体上运用已有的运算符(关于已有的运算符能够看文章底部的官网链接)。这是经过界说类型办法来完成的,这个类型办法的名称便是需求重载的运算符。
举个比如:
structVector2D{
varx=0.0,y=0.0
}
extensionVector2D{
staticfunc+(left:Vector2D,right:Vector2D)->Vector2D{
returnVector2D(x:left.x+right.x,y:left.y+right.y)
}
}
letvector1=Vector2D(x:1.0,y:2.0)
letvector2=Vector2D(x:3.0,y:4.0)
letvectorSum=vector1+vector2
print(vectorSum)//输出成果为Vector2D(x:4.0,y:6.0)
这个示例中,咱们重载了 “+” 运算符,让它能够用于 Vector2D
结构体。现在, “+” 运算符能够承受两个 Vector2D 实例作为参数,并回来一个新的 Vector2D
实例,这个实例的 x 和 y 值是参数的 x 和 y 值的和。
自界说运算符
除了重载运算符,还能够创建自己的自界说运算符。自界说运算符需求运用 operator
关键字进行声明,并需求指定它是一个前缀、中缀或后缀运算符。
这在很多开源项目中都有用到,比如 ObjectMapper
中的 <- 运算符:
infixoperator<-
publicfunc<-<T>(left:inoutT,right:Map){
switchright.mappingType{
case.fromJSONwhereright.isKeyPresent:
FromJSON.basicType(&left,object:right.value())
case.toJSON:
left>>>right
default:()
}
}
还有 >>> 运算符:
infixoperator>>>
publicfunc>>><T>(left:T,right:Map){
ifright.mappingType==.toJSON{
ToJSON.basicType(left,map:right)
}
}
运算符的三个类型
自界说运算符又分为三种类型,即:前缀、中缀和后缀。
1. 前缀运算符(Prefix Operator)
望文生义,这种运算符坐落操作数之前。用 prefix operator
来声明,如下面的比如中,界说了一个前缀运算符 √
,用于取一个浮点数的平方根。
prefixoperator√
prefixfunc√(number:Double)->Double{
returnsqrt(number)
}
letnumber=4.0
print(√number)//输出成果为2.0
2. 中缀运算符(Infix Operator)
这种运算符坐落两个操作数之间,这个也是平常最常用的。用 infix operator
来声明,如下面的比如中,界说了一个中缀运算符 **
,用于进行乘方运算。
infixoperator**:MultiplicationPrecedence
func**(num:Double,power:Double)->Double{
returnpow(num,power)
}
letresult=2.0**3.0
print(result)//输出成果为8.0
3. 后缀运算符(Postfix Operator)
这种运算符坐落操作数之后。如下面的比如中,用 postfix operator
来声明,界说了一个后缀运算符 --
,用于将一个整数减1。
postfixoperator--
postfixfunc--(num:inoutInt)->Int{
num-=1
returnnum
}
varnumber=5
print(number--)//输出成果为4
优先级
学会了自界说运算符后,你可能有个疑问,假如一个表达式中有多个运算符,应该先核算哪个后核算哪个?比如 1 + 2 * 3
,在这个表达式中,乘法运算符 *
的优先级高于加法运算符 +
,因此先进行乘法运算,再进行加法运算,终究成果是 7,而不是 9。
swift 中运用优先级组(precedencegroup)的概念来承认谁的优先级更高,根据 swift 内置的优先级组,优先级是这样摆放的:
BitwiseShiftPrecedence
(位运算符组)> MultiplicationPrecedence
(乘法运算符组)> AdditionPrecedence
(加法运算符组)> RangeFormationPrecedence
(区间运算符组)> CastingPrecedence
> NilCoalescingPrecedence
> ComparisonPrecedence
> LogicalConjunctionPrecedence
> LogicalDisjunctionPrecedence
> TernaryPrecedence
> AssignmentPrecedence
关于这些运算符组中都包括哪些运算符能够到苹果官方网站[1]中检查。
假如你自界说了一个新的运算符,并且想手动修正它的优先级,能够运用 precedencegroup
关键字来界说一个新的优先级组,然后在界说运算符时指定这个优先级组。优先级组能够设置以下几个特点:
-
higherThan
:新的优先级组的优先级高于指定的优先级组。 -
lowerThan
:新的优先级组的优先级低于指定的优先级组。 -
associativity
:运算符的结合性,能够是left
、right
或none
。假如运算符的优先级相同,那么结合性将决定运算的次序。
下面是一个比如:
precedencegroupExponentiationPrecedence{
higherThan:MultiplicationPrecedence
associativity:right
}
infixoperator**:ExponentiationPrecedence
func**(num:Double,power:Double)->Double{
returnpow(num,power)
}
letresult=2.0*3.0**2.0
print(result)//输出成果为18.0
这个示例中界说了一个新的优先级组 ExponentiationPrecedence
,它的优先级高于乘法运算符的优先级组 MultiplicationPrecedence
。然后界说了一个新的中缀运算符 **
,并指定它的优先级组为 ExponentiationPrecedence
。在核算 2.0 * 3.0 ** 2.0
这个表达式时,由于 **
运算符的优先级高于 *
运算符,所以先核算 3.0 ** 2.0
,得到成果 9.0,然后再与 2.0 相乘,得到成果 18.0。
参考资料
[1]
苹果官方网站: developer.apple.com/documentati…
这儿每天共享一个 iOS 的新知识,快来重视我吧
本文同步自微信大众号 “iOS新知”,每天按时共享一个新知识,这儿仅仅同步,想要及时学到就来重视我吧!