迅捷cad
In this tutorial, we’ll be discussing Generics in Swift. We’ll be seeing how we can extend Generic types, use Type Constraints on Generics.
在本教程中,我们将讨论Swift中的泛型。 我们将看到如何扩展泛型类型,对泛型使用类型约束。
迅捷泛型 (Swift Generics)
Generics are used to write flexible and reusable code which can work across multiple types. So instead of creating a different function/struct for every type such as Int, String etc, we can set a Generic type. Generic type is also known as a placeholder type.
泛型用于编写可以跨多种类型工作的灵活且可重用的代码。 因此,我们可以为普通类型设置通用类型,而不是为每种类型(如Int,String等)创建不同的函数/结构。 通用类型也称为占位符类型。
Typically when we pass typed parameters in a function we do something like:
通常,当我们在函数中传递类型化参数时,我们会执行以下操作:
func printMe(a: Int)
{
print(a)
}
printMe(a: 1)
func printMe(a: String)
{
print(a)
}
printMe(a: "Anupam")
Now we can easily use generic parameters instead of creating a different function for each type.
现在,我们可以轻松地使用通用参数,而不是为每种类型创建不同的函数。
For creating a generic function you need to set a placeholder value after the function name in angular brackets as: <Element>
.
为了创建通用函数,您需要在尖括号中的函数名称后面设置一个占位符值: <Element>
。
You need to use the same placeholder value as parameters/return types.
您需要使用与参数/返回类型相同的占位符值。
You can pass more than one placeholder values too.
您也可以传递多个占位符值。
Typically, if the generic parameter placeholder doesn’t represent anything, use T, U, V etc.
通常,如果通用参数占位符不代表任何内容,请使用T,U,V等。
func printMe<T>(a: T)
{
print(a)
}
printMe(a: 1)
printMe(a: "Anupam")
Another example: The classical way of swapping values:
另一个示例:交换值的经典方式:
func swapAandB<T>(_ a: inout T, _ b: inout T) {
let temporaryA = a
a = b
b = temporaryA
}
var x = "hello"
var y = "world"
swapAandB(&x, &y)
print(x)
print(y)
var x1 = 2
var y1 = 3
swapAandB(&x1, &y1)
print(x1)
print(y1)
We can tackle the above rule by using two generic parameters. We’ll have to declare both of them in the function header itself:
我们可以通过使用两个通用参数来解决上述规则。 我们必须在函数标头本身中声明它们两者:
func printTandU<T,U>(a:T,b:U)
{
print("T is \(a) and U is \(b)")
}
printTandU(a: 1, b: "Swift Generics")
通用类型约束 (Generic Type Constraints)
We can constrain a Generic type to conform to a certain type also.
我们也可以约束泛型类型以使其符合某种类型。
class Person{
var name:String?
var age:Int
init(name:String, age:Int)
{
self.name = name
self.age = age
}
}
func printDetails<T: Person>(a: T, b: T)
{
print("a is \(a.name ?? "NA") and age \(a.age)")
print("b is \(b.name ?? "NA") and age \(b.age)")
}
var p1 = Person(name: "Harry Potter",age: 11)
var p2 = Person(name: "Dumbledore",age: 700)
printDetails(a: p1, b: p2)
T conforms to the type Person. So you cannot pass any value that isn’t of the type Person in the above code.
T符合类型Person。 因此,您不能在上面的代码中传递任何不是Person类型的值。
Doing the following would lead to a crash.
执行以下操作会导致崩溃。
class A{
}
printDetails(a: A(), b: A()) //Class A isn't of the type Person.
Another example where the generic type must conform to the protocol:
泛型类型必须符合协议的另一个示例:
func compareAandB<T: Equatable>(a: T, b: T)
{
print("a == b ? \(a==b)")
}
compareAandB(a: 2, b: 3)
compareAandB(a: "Hi", b: "Hi")
Here the ==
won’t work without the Equatable protocol.
如果没有Equatable协议, ==
将无法正常工作。
在泛型类型上使用扩展 (Using Extensions on Generic Types)
We can use Extensions on a Generic type in the following way:
我们可以通过以下方式对泛型类型使用扩展:
struct Stack<T> {
var items = [T]()
mutating func push(_ item: T) {
items.append(item)
}
mutating func pop() -> T {
return items.removeLast()
}
}
var stackOfInt = Stack<Int>()
stackOfInt.push(2)
stackOfInt.push(3)
extension Stack {
var top: T? {
return items.isEmpty ? nil : items[items.count - 1]
}
}
We DO NOT have to set the Generic type in the Extension again.
我们不必在扩展名中再次设置通用类型。
使用where子句 (Using the where clause)
We can use a where clause for an even stricter Generic type constraint checking. In the where clause we can add additional conditions.
我们可以使用where子句进行更严格的泛型类型约束检查。 在where子句中,我们可以添加其他条件。
protocol Hogwarts{}
protocol Muggles{}
class Person : Hogwarts{
var name:String?
var age:Int
init(name:String, age:Int)
{
self.name = name
self.age = age
}
}
class M: Person, Muggles{}
func printDetails<T:Person>(a: T) where T:Muggles {
print("a is \(a.name ?? "NA") and age \(a.age)")
}
var p1 = Person(name: "Harry Potter",age: 11)
var m2 = M(name: "Hermione",age: 700)
var p3 = Person(name: "Ron",age: 11)
printDetails(a: m2)
//printDetails(a: p1)
So in the above code, we add a checker wherein the type T must conform to Muggles protocol as well besides conforming to the class Person.
因此,在上面的代码中,我们添加了一个检查器,其中类型T除了符合类Person之外,还必须符合Muggles协议。
Hence it’ll take only types of the class M in the above code. Not of the class Person.
因此,在上面的代码中,它将仅接受类M的类型。 不属于班级人员。
This brings an end to this tutorial on Swift Generics.
这样就结束了有关Swift Generics的本教程。
迅捷cad