Operator Overloading in Swift tutorial

Source: Internet
Author: User

Operator Overloading in Swift tutorial

Http://www.raywenderlich.com/80818/operator-overloading-in-swift-tutorial Author: Corinne Krych Translator: Meng xiangyue blog: http://blog.csdn.net/mengxiangyue

This is my first translation. It is inevitable that there will be errors. txt is used for translation, so the format is not very good.


In the previous tutorials on the IOS 8 feast series, you have learned that Swift provides many powerful and modern programming features, such as generic, functional programming, enumeration of first class, struct, and other features.

But now there is another Swift feature that you should know and fall in love with. It is an operator overload.

This is a good method. You can use the +,-, *,/, and other operators to apply to any type you like. If you are creative, you can even define your own operators.

For example, we use Operator Overloading in the Swift Sprite Kit utility library (https://github.com/raywenderlich/SKTUtils/tree/swift) code to talk about the addition of multiple CGPoints objects, such as the following code:
Let pt1 = CGPoint (x: 10, y: 20)
Let pt2 = CGPoint (x:-5, y: 0)
Let pt3 = pt1 + pt2
Let pt4 = pt3 * 100

Convenient? Now let's start to reload it and enhance your Swift development capabilities.


Note: This Swift tutorial assumes that you have basic Swift development capabilities. If you are new to Swift, we recommend that you first learn our other Swift tutorials (http://www.raywenderlich.com/tutorials#swift ).


Operator: overview
Note: This part of content is optional. If you want to review the operators and their priorities, you can still view this part of content. If you are familiar with this, you can directly create an empty playground and perform the next part of the content: Overloading ).


First, we create a new playground to help you understand operators.
Add the following code in your playground:
Var simpleSum = 1 + 3
You can see the expected results:
4
There are two operators we are familiar:
1 first, you define a variable named simpleSum and set its value using the value assignment operator (=.
2. Then, you use the plus operator (+) to calculate the sum of two integers.


In this tutorial, you will reload operators like this. But first, you need to understand the concept of priority.
Priority
You may still remember the rules on operator priority that you learned in your school's math class. These rules enable some operators to have a higher priority than other operators, and those with a higher priority are prioritized. For example, multiplication is calculated before addition or subtraction.
Enter the following code in your playground to verify that these rules are also followed in Swift.
Var sumWithMultiplication = 1 + 3-3*2
You can see the following results:
-2
When Arithmetic Operators have the same priority, Swift calculates these operators from left to right. In this example, the operators are calculated in the following order:
1.3*2: minus (Note: This minus can be ignored, mainly for the third step)
2.1 + 3: given the same operator priority, the leftmost operator is preferentially calculated.
3.4-6: this operation relies entirely on the results of the previous high-priority operators.


Note: If you want to know the list of priorities in Swift, you can find the list of completed operator priorities here (https://developer.apple.com/library/prerelease/mac/documentation/Swift/Conceptual/Swift_Programming_Language/Expressions.html#//apple_ref/doc/uid/TP40014097-CH32-XID_720.


Addition is not only applicable to numbers (Adding isn' t Just for Ints)
The integer operation will run as expected, but can you use + to another type?
The following code proves that you can! Add the following code to your playground:
Var sumArray = [1, 2] + [1, 2]
In this case, Swift interprets + as an append Command. But what if you want to add the elements at each position? We all know that this is called vector addition ).
Of course, you can define a method to implement this function. Add the following code to your playground and try again:
Func add (left: [Int], right: [Int])-> [Int] {
Var sum = [Int] ()
Assert (left. count = right. count, "vector of same length only ")
For (key, v) in enumerate (left ){
Sum. append (left [key] + right [key])
}
Return sum
}
In this way, you define a global method. This method is used to calculate the sum of two input arrays. First, check whether the length of the two input arrays is consistent, add the elements at each position of the two arrays and store them in a new array.
Add the following code to verify that your new method works properly:
Var arr1 = [1, 1]
Var arr2 = [1, 1]
Var arr3 = add (arr1, arr2)
You will see the following output in the console:
[2, 2]
It's great! But we have to call a method to do this. Why can't we use the + operator instead?

Operator overload
Operator Overloading allows you to change the operating methods of existing operators in specific struct and classes ). Isn't that exactly what you want?-change the way the + operator works on the int array.
Because Operator Overloading is applied to the global playground, you can create a new playground to avoid affecting the original example. Then add the following code to your playground:
Func + (left: [Int], right: [Int])-> [Int] {// 1
Var sum = [Int] () // 2
Assert (left. count = right. count, "vector of same length only") // 3
For (key, v) in enumerate (left ){
Sum. append (left [key] + right [key]) // 4
}
Return sum
}
You have defined a global function called +, which adds two int arrays and returns an int array. Next, let's take a look at how it works:
1. Note that this method definition is not special. It is a common method definition, except that you use + as its function name.
2. You have created an empty Int array.
3. This example can only work in the case that two arrays are the same, so here we use assert to ensure that it is like this.
4. Then you enumerated the array on the left and added the value of the array on the right at the same position.
Add the following code to your playground and test this method:
Var sumArray1 = [1, 2, 3] + [1, 2, 3]
The final result is the expected vector addition Operator! You will see the following results:
[2, 4, 6]
Of course, Operator Overloading is not pleasant. When a person looks at your code and wants the operator's default behavior, the operator overload will confuse them. Even so, it still cannot prevent you from rewriting the + operator to allow it to perform the subtraction of numbers. Of course, this risk is obvious.
Image http://cdn4.raywenderlich.com/wp-content/uploads/2014/09/OperatorRage.png
Remember the principle of Operator Overloading: greater capacity, greater responsibility (with great power comes great responsibility ).
Typically, when you overload an operator on a new object, you need to maintain its original semantics rather than defining different (and confusing) behaviors.
In this example, the overloaded behavior maintains the original semantics: vector addition is still an addition. However, when you overwrite the default adding behavior of the Int array, you may want to use the Int array to add the default behavior in a few months. This will be confusing.
Fortunately, Swift allows you to define your own custom operators.
Custom Operators
There are three steps to define a custom OPERATOR:
1. Name your operator
2. Select a type
3. Set its priority and combination
Define Your Operators
Now you must select a character as your operator. Custom operators can be '/', '=', '-', '+', and ,! , *, %, <,>, &, |, ^ ,~ Or begin with a Unicode character. This gives you a large range of operators to select. But don't be so happy. When selecting a keyboard, you must also consider repeating the input with less typing times.
In this case, you can copy and paste the Unicode Character delimiter to adapt to the addition implementation in your example.
Select a type
In Swift, you can define operators for one, two, and three elements. They indicate the number of numbers operated by operators.
The unary operator is related to an operand, such as the rear ++ (I ++) or the front ++ (++ I) operator. They depend on the position where the operator and the operand appear.
Binary operators are inserted because they appear in the middle of two operators, such as 1 + 1.
The ternary operator has three operands. In Swift ,? : The condition operator is the only three-object operator, such as? B: c.
You should select an appropriate type based on the number of operands of your operators. To add two arrays, define the binary operator.
Set its priority and combination
Since the operator definition is global, you must be careful to select the priority and associativity of your custom operator.
This is tricky, so there is a better way to find a similar standard operator in Swift language reference (https://developer.apple.com/library/mac/documentation/Swift/Conceptual/Swift_Programming_Language/Expressions.html#//apple_ref/doc/uid/TP40014097-CH32-XID_720) and then use the same semantics. For example, when defining vector addition, you can use the same priority and combination as the + operator.
Write your custom Operators
Return to your playground and enter the following code to define your custom operators. For simplicity, you may want to copy and paste the producer. (Note: It may be used to copy this character)
Infix operator {associatificleft precedence 140} // 1
Func trim (left: [Int], right: [Int])-> [Int] {// 2
Var sum = [Int] (count: left. count, repeatedValue: 0)
Assert (left. count = right. count, "vector of same length only ")
For (key, v) in enumerate (left ){
Sum [key] = left [key] + right [key]
}
Return sum
}
This code is similar to the reload in the first part. This Code mainly performs the following steps:
* Defines an infix/binary operator. It has two operands and is located on both sides of the operator.
* The naming operator is operator.
* Set the Union to left, indicating that when the operator has the same priority, it combines the order of operators from left to right.
* Set priority to 140, which is the same priority as Int addition, which can be viewed in Swift language reference (https://developer.apple.com/library/mac/documentation/Swift/Conceptual/Swift_Programming_Language/Expressions.html#//apple_ref/doc/uid/TP40014097-CH32-XID_720.
The code in the second part is similar to what you saw earlier. It adds the two arrays one by one. Add the following code to your playground to test this new operator:
Var sumArray = [1, 2, 3] Values [1, 2, 3]
You will see the same result as the previous overload method, but this time you have an operator with different semantics.
Bonus Round!
Now you know how to create a custom operator. It's time to challenge yourself. You have created a lift operator to execute the addition of vectors, so use the current knowledge to create? Operator. Similar methods are used to subtract two arrays. Do your best to view the following answers.
Infix operator? {Associatificleft precedence 140}
Func? (Left: [Int], right: [Int])-> [Int] {
Var minus = [Int] (count: left. count, repeatedValue: 0)
Assert (left. count = right. count, "vector of same length only ")
For (key, v) in enumerate (left ){
Minus [key] = left [key]-right [key]
}
Return minus
}
Test:
Var subtractionArray = [1, 2, 3]? [1, 2, 3]


Remember similar Operators
If you define a new operator, do not forget to define any related operators.
For example, the plus operator (+ =) combines the plus and value assignment operators to form an operator. Since your new operator is syntactically the same as the addition operator, a good method is to define an addition or equal operator.
Add the following code to Operator2.playground:
Infix operator = {associatificleft precedence 140} // 1
Func outputs = (inout left: [Int], right: [Int]) {// 2
Left = left outer right
}
The first line is declared like the except operator, which uses a combination operator.
Note that in the second line, the input parameter on the left of the combined operator is declared as inout, which indicates the value of this parameter and will be directly modified inside the operator method. As a result, this operator does not need to return a value. It directly modifies your input value.
Add the following code in your playground to test whether the operator runs as you want.
You will see the following output in the console:
[3, 5, 7]
Now, it's not difficult to define your own operators.


Is not just a type definition Operator
Now you want to define a vector addition operator for decimal places.
One way is to reload a new operator for Double and Float according to the method of overloading the operator for Int. It is only a few lines of code, but you must use copy/paste. If you are like me-code cleanliness-copying code is not your first choice, it will make your code difficult to maintain.
Use generics to save
Fortunately, Swift generics can help you implement this function. If you need to review Swift's Generics, find our previous article Swift Generics Tutorial (http://www.raywenderlich.com/82572/swift-generics-tutorial ).
To have a clean context, we create a playground. Add the following code to your playground:
Infix operator {associatificleft precedence 140}
Func Functions (Left: [T], right: [T])-> [T] {// 1
Var minus = [T] ()
Assert (left. count = right. count, "vector of same length only ")
For (key, v) in enumerate (left ){
Minus. append (left [key] + right [key]) // 2
}
Return minus
}
In the first line, you define a generic type function struct, which has a type placeholder T. Playground is not happy here. You can see a compilation error: cocould not find an overload for '+' that accepts the supplied arguments.
This error comes from the second line. When we try to use the + operator to operate on the left and right parameters of the T type, an error occurs. Swift does not know how to use the + operator for these parameters, because it does not know what type these parameters are.
Extend a protocol
Remove your code and use the following code instead:
Protocol Number {// 1
Func + (l: Self, r: Self)-> Self // 2
}

Extension Double: Number {}// 3
Extension Float: Number {}
Extension Int: Number {}

Infix operator {associatificleft precedence 140}
Func Functions (Left: [T], right: [T])-> [T] {// 4
Var minus = [T] ()
Assert (left. count = right. count, "vector of same length only ")
For (key, v) in enumerate (left ){
Minus. append (left [key] + right [key])
}
Return minus
}
You have done a lot of things here. Let's look back at these steps:
1. You have defined a Protocol Number
2. This Number defines an operator +
3. You have created an extension for Double, Float, and Int to enable them to implement the Number protocol.
4. You have used a type constraint to require T to implement the Number Protocol
Finally, you tell the compiler how T processes the + operator. Now that you have fixed the compilation error, use the following code to test the Double array and Int array respectively:
Var doubleArray = [2.4, 3.6] average [1.6, 2.4]
Var intArray = [2, 4] Values [1, 2]
You will see the following output in the console:
[4.0, 6.0]
[3, 6]
Now this operator works normally under multiple data types without Replicating Code. If you want to add more numeric types, you only need to simply implement the Number protocol.


How can I use Operator Overloading in real life?
Don't you ever think about it. If it doesn't work, I will let you waste so much time in this tutorial? This section will show you a real example to show you how to better use Operator Overloading in your project.
Operator and CGPoints
For this Demo, you will use the SKTUtils library (https://github.com/raywenderlich/SKTUtils/tree/swift), which is a collection of convenient Sprite Kit help classes that were meant for iOS Games by Tutorials (http://www.raywenderlich.com/store/ios-games-by-tutorials) this book is written in the second version.
You can find the repository of this framework on github. Enter the following code on your command line interface to Clone the branch of the Repository:
Git clone https://github.com/raywenderlich/SKTUtils.git -- branch swift
You downloaded the zip package from the repository branch on github.
Note: From Xcode6 beta 5, it is possible to introduce your own library in playground. All you need to do is bind the framework and playground to a workspace. If you want to know
Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.