Swift generics
Swift provides generics that allow you to write flexible and reusable functions and types.
The Swift standard library is built from generic code.
The array and dictionary types of Swift are generic sets.
You can create one. Int
array, or you can create a String
array, or even an array of type data of any other Swift.
The following example is a non-generic function exchange
in exchange for two. Int
Value:
Example
//
Define a function funcswapTwoInts (\ a: inoutInt, \ _b: inoutInt) {lettemporaryA=aa=bb=temporaryA} varnumb1=100varnumb2=200print to exchange two variables
SwapTwoInts (&numb1,&numb2) print() after swapping data:
And \ \ (numb2)
The output of the above program execution is as follows:
Data before exchange: 100 and 200
Exchange data: 200 and 100
The above example only tries and swaps variables of type Int. If you want toexchange two String
value or Double
value, you have to rewrite the corresponding function, such as swapTwoStrings(_:_:)
and swapTwoDoubles(_:_:)
, as follows:
String
and Double
value exchange function
funcswapTwoStrings(\_a:inoutString,\_b:inoutString){lettemporaryA=aa=bb=temporaryA}funcswapTwoDoubles(\_a:inoutDouble,\_b:inoutDouble){lettemporaryA=aa=bb=temporaryA}
Judging from the above code, the functional code is the same, but the type is different, so we can use generics to avoid repetitive coding.
Generics use placeholder type names (represented here by the letter T) instead of actual type names (for example, Int
、 String
or Double
).
func swapTwoValues<T>(_ a: inout T, _ b: inout T)
swapTwoValues
this is followed by the placeholder type name (T) and enclosed in angle brackets ( <T>
). This angle bracket tells Swift which T is. swapTwoValues(_:_:)
a placeholder type name within the function definition, so Swift does not look for the actual type named T.
The following example is a generic function exchange
in exchange for two. Int
and String
value:
Example
//
Define a function funcswapTwoValues<T>(\ a: inoutT, \ _b: inoutT) {lettemporaryA=aa=bb=temporaryA} varnumb1=100varnumb2=200print ("Data before exchange: \ \ (numb1)")
SwapTwoValues (&numb1,&numb2) print() after swapping:
Before exchanging data with \ \ (numb2) ") varstr1=" A "varstr2=" B "print(): \ \ (str1)
SwapTwoValues (&str1,&str2) print() after swapping:
And \ \ (str2)
The output of the above program execution is as follows:
Data before exchange: 100 and 200
Exchange data: 200 and 100
Data before exchange: A and B
Exchange data: B and A
Generic type
Swift allows you to define your own generic types.
Custom classes, structures, and enumerations act on any type, as Array
and Dictionary
usage.
Next, let’s write a program called Stack
the generic collection type of(stack), the stack only allows new elements to be added at the end of the collection (called on the stack), and can only remove elements from the end (called off the stack).
The image is parsed from left to right as follows:
Three values are in the stack.
The fourth value is pushed to the top of the stack.
There are now four values in the stack, with the most recent value at the top.
The top value in the stack is removed, or called off the stack.
After removing a value, the stack now has only three values.
The following example is a non-generic version of the stack to Int
the stack of type An is an example:
Int type stack
structIntStack{varitems=[Int]()mutatingfuncpush(\_item:Int){items.append(item)}mutatingfuncpop()->Int{returnitems.removeLast()}}
This structure uses a file named items
of Array
property to store the value. Stack
provide two methods:push(_: )
and pop()
used to press values into and remove values from the stack These methods are marked as mutating
. Because they need to modify the structure s items
array.
Above. IntStack
structures can only be used for Int
type. However,you can define a generic type Stack
structure so that any type of value can be processed.
Here is a generic version of the same code:
Stack of generics
structStack<Element>{varitems=[Element]()mutatingfuncpush(\_item:Element)
{items.append(item)}mutatingfuncpop()->Element{returnitems.removeLast()}}
varstackOfStrings=Stack<String>()print("String element push:")
stackOfStrings.push("google")stackOfStrings.push("runoob")print
(stackOfStrings.items);letdeletetos=stackOfStrings.pop()print
("Stack element:"+deletetos)varstackOfInts=Stack<Int>()print("Pushing integer elements onto the stack:")
stackOfInts.push(1)stackOfInts.push(2)print(stackOfInts.items);
The execution result of the instance is as follows:
String element push:
["google", "runoob"]
Stack element: runoob
Pushing integer elements onto the stack:
[1, 2]
Stack
basically and IntStack
are the same, placeholder type parameter Element
instead of the actual Int
type.
In the above example Element
is used as placeholders in the following three places:
Create
items
Property, use inElement
initializes it with an empty array of type.Designation
push(_:)
the unique parameter of the methoditem
the type of must beElement
type.Designation
pop()
the return type of the method must beElement
type.
Extended generic type
When you extend a generic type (using the extension
keyword), you do notneed to provide a list of type parameters in the extended definition. More conveniently, the list of type parameters declared in the original type definition can be used in the extension, and these parameter names from the original type are used as references to the type parameters in the original definition.
The following example extends generic types Stack
to which you added a file named topItem
, which returns the element at the top of the current stack without removing it from the stack