Latest web development tutorials

스위프트 제네릭

스위프트는 일반 유연성을 제공하고 재사용 가능한 기능과 유형을 작성할 수 있습니다.

스위프트 표준 라이브러리는 일반 코드에 의해 구성된다.

스위프트 배열과 사전 유형은 일반 집합입니다.

당신은 다른 스위프트의 모든 유형이 될 수있는 String 배열, 또는 데이터 배열을 만들 수있는 int 배열을 만들 수 있습니다.

다음 예제에서는 두 값의 교환이 아닌 일반 함수 지능 교환입니다 :

// 定义一个交换两个变量的函数
func exchange(inout a: Int, inout b: Int) {
    let temp = a
    a = b
    b = temp
}

var numb1 = 100
var numb2 = 200

print("交换前数据: \(numb1) 和 \(numb2)")
exchange(&numb1, b: &numb2)
print("交换后数据: \(numb1) 和 \(numb2)")

위의 프로그램 실행 출력은 다음과 같습니다

交换前数据: 100 和 200
交换后数据: 200 和 100

범용 기능은 지능 또는 문자열로, 모든 유형에 액세스 할 수 있습니다.

다음의 예는 교환 스왑이 지능과 문자열 값에 대한 일반적인 기능입니다 :

func exchange<T>(inout a: T, inout b: T) {
    let temp = a
    a = b
    b = temp
}

var numb1 = 100
var numb2 = 200

print("交换前数据:  \(numb1) 和 \(numb2)")
exchange(&numb1, b: &numb2)
print("交换后数据: \(numb1) 和 \(numb2)")

var str1 = "A"
var str2 = "B"

print("交换前数据:  \(str1) 和 \(str2)")
exchange(&str1, b: &str2)
print("交换后数据: \(str1) 和 \(str2)")

위의 프로그램 실행 출력은 다음과 같습니다

交换前数据:  100 和 200
交换后数据: 200 和 100
交换前数据:  A 和 B
交换后数据: B 和 A

(일반적으로이 경우 문자 T로 표시) 자리 표시 자 유형 이름을 사용하여이 기능을 대신 (예 : INT, 문자열 또는 두 번으로) 실제 유형 이름의 일반 버전입니다. 자리 표시 자 유형 이름은 어떤 종류의 T를 제안하지해야하지만, 그것은을 제안하고 b는 관계없이 T가 나타내는 종류의, 같은 종류의 T해야합니다. 만 교환 (_ : _ : T가 나타내는 실제 유형을 판별하기 위해 각 통화 유형에 전달 기능.

또 다른 차이점은 자리 표시 자 타입 (T)의 일반적인 이름 뒤에 후자의 기능 이름 (꺾쇠 괄호로 묶여 있다는 것입니다 ). 꺾쇠 괄호는 T가 교환 (이라고 스위프트에게 _ : _ : 정의 된 유형의 기능. T가 자리라는 형식이기 때문에, 신속한 실제 형 T. 이름을 찾을 수 없습니다


일반 유형

스위프트는 자신의 일반적인 유형을 정의 할 수있다.

사용자 정의 클래스, 구조체, 및 열거 형은 배열 및 사전 사용 등 모든 유형에 적용.

struct TOS<T> {
    var items = [T]()
    mutating func push(item: T) {
        items.append(item)
    }
    
    mutating func pop() -> T {
        return items.removeLast()
    }
}

var tos = TOS<String>()
tos.push("Swift")
print(tos.items)

tos.push("泛型")
print(tos.items)

tos.push("类型参数")
print(tos.items)

tos.push("类型参数名")
print(tos.items)


let deletetos = tos.pop()

위의 프로그램 실행 출력은 다음과 같습니다

["Swift"]
["Swift", "泛型"]
["Swift", "泛型", "类型参数"]
["Swift", "泛型", "类型参数", "类型参数名"]

확장 된 제네릭 형식

당신이 (확장 키워드를 사용) 시간의 제네릭 형식을 확장하면 확장 된 정의의 형식 매개 변수 목록을 제공 할 필요가 없습니다. 더 편리하게는리스트 선언 프리미티브 타입 파라미터 타입 정의 사용으로 확장 할 수 있고, 원래의 형태에서 파라미터 이름이 입력 파라미터의 원래의 정의를 기준으로 사용된다는 것이다.

다음 예는 제 1 계산라는 판독 전용 속성을 추가, 일반 TOS 유형 확장, 상기 스택 엘리먼트의 현재 정상 리턴 스택으로부터 제거되지 않는다.

struct TOS<T> {
    var items = [T]()
    mutating func push(item: T) {
        items.append(item)
    }
    
    mutating func pop() -> T {
        return items.removeLast()
    }
}

var tos = TOS<String>()
tos.push("Swift")
print(tos.items)

tos.push("泛型")
    print(tos.items)
    
    tos.push("类型参数")
    print(tos.items)
    
    tos.push("类型参数名")
    print(tos.items)

// 扩展泛型 TOS 类型
extension TOS {
    var first: T? {
        return items.isEmpty ? nil : items[items.count - 1]
    }
}

if let first = tos.first {
    print("栈顶部项:\(first)")
}

위의 프로그램 실행 출력은 다음과 같습니다

["Swift"]
["Swift", "泛型"]
["Swift", "泛型", "类型参数"]
["Swift", "泛型", "类型参数", "类型参数名"]
栈顶部项:类型参数名

형 제약

유형 제약 유형 매개 변수가 지정된 클래스에서 상속 또는 특정 프로토콜 또는 조성물을 준수해야 함을 지정합니다.

형 제약 구문

당신은 유형 매개 변수 체인의 한 부분으로, 콜론으로 구분 유형 매개 변수 이름 뒷면의 형식 제약 조건을 작성할 수 있습니다. (신택스 같은 범용 형)를 다음과 같이 일반적인 기능 제한 구문의 유형에 기초하여 이러한 작용은 :

func someFunction<T: SomeClass, U: SomeProtocol>(someT: T, someU: U) {
    // 这里是函数主体
}

// 函数可以作用于查找一字符串数组中的某个字符串
func findStringIndex(array: [String], _ valueToFind: String) -> Int? {
    for (index, value) in array.enumerate() {
        if value == valueToFind {
            return index
        }
    }
    return nil
}

let strings = ["cat", "dog", "llama", "parakeet", "terrapin"]
if let foundIndex = findStringIndex(strings, "llama") {
    print("llama 的下标索引值为 \(foundIndex)")
}

위의 프로그램 실행 출력은 다음과 같습니다

llama 的下标索引值为 2

연결 유형의 예

스위프트 typealias은 협회의 유형을 설정하는 데 사용되는 키워드.

때로는 하나를 선언 프로토콜을 정의하거나 정의의 프로토콜 부분의 더 많은 관련 유형은 매우 유용하다.

protocol Container {
    // 定义了一个ItemType关联类型
    typealias ItemType
    mutating func append(item: ItemType)
    var count: Int { get }
    subscript(i: Int) -> ItemType { get }
}

// 遵循Container协议的泛型TOS类型
struct TOS<T>: Container {
    // original Stack<T> implementation
    var items = [T]()
    mutating func push(item: T) {
        items.append(item)
    }
    
    mutating func pop() -> T {
        return items.removeLast()
    }
    
    // conformance to the Container protocol
    mutating func append(item: T) {
        self.push(item)
    }
    
    var count: Int {
        return items.count
    }
    
    subscript(i: Int) -> T {
        return items[i]
    }
}

var tos = TOS<String>()
tos.push("Swift")
print(tos.items)

tos.push("泛型")
print(tos.items)

tos.push("参数类型")
print(tos.items)

tos.push("类型参数名")
print(tos.items)

위의 프로그램 실행 출력은 다음과 같습니다

["Swift"]
["Swift", "泛型"]
["Swift", "泛型", "参数类型"]
["Swift", "泛型", "参数类型", "类型参数名"]

어디 문

제약 조건의 종류는 제한 일반적인 함수 또는 클래스의 유형의 정의 준수를 보장합니다.

당신은 명령문의 매개 변수를 정의 할 수있는 매개 변수 목록에서 제약.

어디 문이 하나 이상의 협회에 대한 제약의 유형, 뒤에 뒷면의 유형 매개 변수 목록, 다음에 문을 작성할 수 있습니다 (또는) 하나 이상의 유형과 (평등) 관계 사이의 연결 유형에 해당.

다음 예는 컨테이너의 두 인스턴스를 같은 순서로 같은 요소가 포함되어 있는지 여부를 확인하는 데 사용 allItemsMatch라는 이름의 일반적인 기능을 정의합니다.

모든 요소가 일치 할 경우, 그렇지 않으면 거짓, 사실의 부울 값으로 돌아갑니다.

protocol Container {
    typealias ItemType
    mutating func append(item: ItemType)
    var count: Int { get }
    subscript(i: Int) -> ItemType { get }
}

struct Stack<T>: Container {
    // original Stack<T> implementation
    var items = [T]()
    mutating func push(item: T) {
        items.append(item)
    }
    
    mutating func pop() -> T {
        return items.removeLast()
    }
    
    // conformance to the Container protocol
    mutating func append(item: T) {
        self.push(item)
    }
    
    var count: Int {
        return items.count
    }
    
    subscript(i: Int) -> T {
        return items[i]
    }
}

func allItemsMatch<
    C1: Container, C2: Container
    where C1.ItemType == C2.ItemType, C1.ItemType: Equatable>
    (someContainer: C1, anotherContainer: C2) -> Bool {
        // 检查两个Container的元素个数是否相同
        if someContainer.count != anotherContainer.count {
            return false
        }
        
        // 检查两个Container相应位置的元素彼此是否相等
        for i in 0..<someContainer.count {
            if someContainer[i] != anotherContainer[i] {
                return false
            }
        }
        // 匹配所有项,返回 true
        return true
}

var tos = Stack<String>()
tos.push("Swift")
print(tos.items)

tos.push("泛型")
print(tos.items)

tos.push("Where 语句")
print(tos.items)

var eos = ["Swift", "泛型", "Where 语句"]
print(eos)

위의 프로그램 실행 출력은 다음과 같습니다

["Swift"]
["Swift", "泛型"]
["Swift", "泛型", "Where 语句"]
["Swift", "泛型", "Where 语句"]