迅捷cad_迅捷泛型

迅捷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)
You can only pass the same type in all the T’s. Setting different types would cause compiler error.
您只能在所有T中传递相同的类型。 设置不同的类型将导致编译器错误。

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.
Subclasses would conform to the the generic parameter type.
子类将符合通用参数类型。

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的本教程。

翻译自: https://www.journaldev.com/20985/swift-generics

迅捷cad

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值