Today, let's talk about operator overloading in Swift, which is very useful, but also quite risky. What is called "the greater the capacity, the greater the responsibility," the phrase used to describe operator overloading is the most appropriate. It can make your code more concise, or it can make a function call smelly and long. And for those who haven't read your code, the use of the operator also makes the code less readable.
Careful introduction, on-demand use. For example, when you connect two strings, you can do so by overloading the addition. Even if you just type a plus sign on the screen, you can respond to a web link, play a piece of music, or do anything else you can. However, too complex a function is simply a disaster for coding, and it is reasonable to overload the operator only when necessary, without doing anything superfluous. If you have to do something strange, then take an obvious and appropriate function name for the network response function.
Whenever you want to use operator overloading, you need to consider whether it is worth overloading it rather than using a function call. A function call may be a lot of trouble, but it's more accurate to express its function (if the function name is just right). Operator overloading is a good solution if you want to frequently do operations similar to subtraction assignment comparisons.
Operator overloading
In Swift you should use the overloaded operator as you normally would with operators. Although there are still some deficiencies, the following example is sufficient to illustrate the use of overloaded operators. This code calculates the difference between the two NSDate objects, using the form of "laterdate–initialdate":
Func-(Left:nsdate, right:nsdate), nsdatecomponents{let Mostunits:nscalendarunit =. Yearcalendarunit |. Monthcalendarunit |. Daycalendarunit |. Hourcalendarunit |. Minutecalendarunit |. Secondcalendarunit Let components = Nscalendar.currentcalendar (). Components (Mostunits, Fromdate:right, Todate:lef T, Options:nil) return components}
In this function, the first line looks a lot, but mostunits represents the list of date units (Nscalendarunit) that we care about, where I choose to focus on the year, month, day, time, minute, and second. It is important to note that this is not only the flag of these date units, but also a lot of options, if I want to know the number of weeks between two dates I can replace these with other flags, using these different flags can meet our most requirements for date calculation. On the next line, a Nsdatecomponents object is created using the components () method of the current time Nscalendar.currentcalendar (), and then the object is returned at the end of the method.
The operation between the two values becomes the infix operation, and the operation overload has two kinds: suffix operation and prefix operation. For example, ++i and i++ are prefix and suffix operations respectively.
As you can see, the so-called overload in Swift is simply trickery, which is actually just a function call, except that the function name becomes a symbol. We specify the type of the left and right arguments in the expression, and also specify that the data type returned by the calculation must be a Nsdatecomponents object, the following is the code:
let initialdate = nsdate () let components = Nsdatecomponents () components.year = 1components.month = 5components.minute = 42let laterdate = nscalendar.currentcalendar (). Datebyaddingcomponents (components, toDate: initialdate, options: nil)!//test the overloaded operatorlet difference = laterdate - initialdate//resultsprintln (difference.year) // outputs: "1" println (difference.month) //Outputs: "5" println (difference.day) //Outputs: "0" println (difference.hour) //Outputs: "0" println (Difference.minute) //Outputs: "println" (Difference.second) //outputs: "0"
Here are some settings, but most of them are well understood. We first initialize a date data, whose value is the date the NSDate object was created, and a Nsdatecomponents object that contains its own value for the month and the minute of the property. Then use Nscalendar's Datebyaddingcomponents method to set the Laterdate to 1 years, 5 months, and 42 minutes later. Then after testing the overloaded new function "-" operator, you will see that the result of the last subtraction output is exactly the time difference we set.
I think this kind of overload is still a bit of a use, we can calculate as usual using mathematical subtraction. However, some of the hypothetical conditions are hidden here: first I have mentioned that flag for Nscalendarunit is only used for some rather than all, and secondly, I have explicitly used Nscalendar's current date (Currentcalendar) in the overloaded function that is not shown here. Finally, it sets the attribute value of the computed result difference to 0, but we do not actually want to use other properties. But as I know, some people might think of encapsulating all the attributes to solve.
If you use normal function calls instead of overloaded operators, you can clearly see which format dates are used, which flags are selected, and which properties are set in Diffrence. That's why I say overloaded operators are just "a bit of a use". The reason is that it is to the reader of the code, want to know exactly what assumptions are hidden in the function, only the source of the overloaded operators to see.
Equatable protocol
The overloaded operators in Swift are still some of the more nice places. You can implement a comparison of a custom class by overloading the "= =" operator. If you want to implement this function you will need to use the Equatable protocol, the Equatable protocol is mainly used for generic programming (for Swift's generic programming can refer to here). If you overload the "= =" operator According to the Equatable protocol, you no longer need to reload the "! =" operator (because the overload of "! =" is the logical no for "= =").
Overloading the "= =" method is consistent with the overloaded way of other infix operations, as we did in the "-" overloads mentioned above:
globally scoped operator functionfunc == (left: temperature, right: temperature) -> bool{ if left. C == right. c { return true } else { return false }}//custom type itselfstruct temperature:equatable{ let c: double}//testlet tempone = temperature (C: 15) let temptwo = temperature (c: 35) let tempthree = temperature (C: 15) let OneTwoEquality = (Tempone == temptwo) // stores: falselet onethreeequality = (Tempone == tempthree) //stores: true
Now we can use the "= =" overloaded operation to compare two temperature instances. If you want to overload an operator then it must have a corresponding global function, even defined outside the type.
One of the great thing about operation overloading in Swift is the comparable protocol. As you follow the Equatable protocol, you will need to reload a "<" method when you are implementing the comparable protocol. In addition, if you overload the "= =" and ">" operators, the compiler will calculate for you several other operators "! =", "<", "& Lt;=", and ">=". You can see an example here, which is also an example of the Equatable protocol.
Summarize
The test environment for all the code in this article is Xcode 6.0.1.
Earlier I discussed the subtraction of nsdate because it hides a lot of hypothetical conditions when it is called. Here's a reminder: Consider this example when you're thinking about whether you want to implement overloaded operators in your code. If you want to use the same unitflag to overload the subtraction of the implementation date in your code, you need to write more code to consider multiple scenarios.
If you want to overload the built-in types and operator overloads of types that you do not want to modify (or cannot modify), you can add this overloaded function inside the extension. And this overloaded function needs to be the global scope, and placed in any of your extended files.
There are some operators that cannot be overloaded, the most obvious being the assignment operation "=" (an equal sign). Even if you overload, think about the frequency of the assignment operation, and I will not have any interest in the resulting error. Here is an article from Tammo Freese, you can find out which operators can not be overloaded.
Another discussion on Swift operator overloading