Swiftプログラミングにおける汎用解析
func swapTwoInts(inout a: Int, inout b: Int)
let temporaryA = a
a = b
b = temporaryA
}
この関数は、書き込み読み出し(in-out)パラメータを用いてaとbの値を交換します.書き込み読み出しパラメータを参照してください.
swapTwoInts関数はbの元の値をaに交換したり、aの元の値をbに交換したりすることができます.この関数を呼び出して2つのInt変数の値を交換することができます.
var someInt = 3
var anotherInt = 107
swapTwoInts(&someInt, &anotherInt)
println("someInt is now \(someInt), and anotherInt is now \(anotherInt)")
// "someInt is now 107, and anotherInt is now 3"
swapTwoInts , Int , String Double, , swapTwoStrings swapTwoDoublesfunctions, :
func swapTwoStrings(inout a: String, inout b: String) {
let temporaryA = a
a = b
b = temporaryA
}
func swapTwoDoubles(inout a: Double, inout b: Double) {
let temporaryA = a
a = b
b = temporaryA
}
swapTwoInts、swapTwoStrings、swapTwoDoubles関数の機能は同じであることに気づくかもしれませんが、唯一の違いは、Int、String、Doubleの変数タイプが異なることです.
しかし、実際の応用では、通常、より強力で、可能な限り柔軟性を考慮した単一の関数が必要です.2つの任意のタイプの値を交換することができます.幸いなことに、汎用コードはこの問題を解決します.(このような汎用関数は後で定義されています.)
注意:すべての3つの関数では、aとbのタイプは同じです.aとbが同じタイプでない場合、それら2つは値を交換できません.Swiftはタイプが安全な言語なので、Stringタイプの変数とDoubleタイプの変数が値を交換することは許可されません.必ずしなければならない場合、Swiftはコンパイルエラーを報告します.
汎用関数:タイプパラメータ汎用関数は、「Int」または「String」などの任意のデータ型にアクセスできます.
func exchange(inout a: T, inout b: T) {
let temp = a
a = b
b = temp
}
var numb1 = 100
var numb2 = 200
println("Before Swapping Int values are: \(numb1) and \(numb2)")
exchange(&numb1, &numb2)
println("After Swapping Int values are: \(numb1) and \(numb2)")
var str1 = "Generics"
var str2 = "Functions"
println("Before Swapping String values are: \(str1) and \(str2)")
exchange(&str1, &str2)
println("After Swapping String values are: \(str1) and \(str2)")
Playgroundを使用して上記のプログラムを実行すると、以下の結果が得られます.
Before Swapping Int values are: 100 and 200
After Swapping Int values are: 200 and 100
Before Swapping String values are: Generics and Functions
After Swapping String values are: Functions and Generics
関数exchange()は、上記のスキームで説明され、タイプパラメータ値として使用されるものと交換するために使用される.これは初めてで、関数exchange()が呼び出されてInt値を返し、2回目の関数exchange()がString値を返します.複数のパラメータタイプには、括弧で区切られたカンマを含めることができます.
タイプパラメータは、タイプパラメータを持つ目的を理解するためにユーザー定義として命名されます.Swiftは汎用型パラメータとしての名前を提供する.ただし、イメージ配列やディクショナリパラメータは、キー、値として名前を付けて、入力がディクショナリに属することを決定することもできます.
汎用タイプ
struct TOS {
var items = [T]()
mutating func push(item: T) {
items.append(item)
}
mutating func pop() -> T {
return items.removeLast()
}
}
var tos = TOS()
tos.push("Swift")
println(tos.items)
tos.push("Generics")
println(tos.items)
tos.push("Type Parameters")
println(tos.items)
tos.push("Naming Type Parameters")
println(tos.items)
let deletetos = tos.pop()
Playgroundを使用して上記のプログラムを実行すると、以下の結果が得られます.
[Swift]
[Swift, Generics]
[Swift, Generics, Type Parameters]
[Swift, Generics, Type Parameters, Naming Type Parameters]
拡張汎用タイプ拡張スタックプロパティは、プロジェクトの上部にextensionキーが含まれていることを知っておく必要があります.
struct TOS {
var items = [T]()
mutating func push(item: T) {
items.append(item)
}
mutating func pop() -> T {
return items.removeLast()
}
}
var tos = TOS()
tos.push("Swift")
println(tos.items)
tos.push("Generics")
println(tos.items)
tos.push("Type Parameters")
println(tos.items)
tos.push("Naming Type Parameters")
println(tos.items)
extension TOS {
var first: T? {
return items.isEmpty ? nil : items[items.count - 1]
}
}
if let first = tos.first {
println("The top item on the stack is \(first).")
}
Playgroundを使用して上記のプログラムを実行すると、以下の結果が得られます.
[Swift]
[Swift, Generics]
[Swift, Generics, Type Parameters]
[Swift, Generics, Type Parameters, Naming Type Parameters]
スタックの上部にあるプロジェクト名のタイプパラメータ.
タイプ制約Swift言語では、タイプ制約で特定のクラスからタイプパラメータを継承するか、プロトコルの一貫性基準を確保するかを指定できます.
func exchange(inout a: T, inout b: T) {
let temp = a
a = b
b = temp
}
var numb1 = 100
var numb2 = 200
println("Before Swapping Int values are: \(numb1) and \(numb2)")
exchange(&numb1, &numb2)
println("After Swapping Int values are: \(numb1) and \(numb2)")
var str1 = "Generics"
var str2 = "Functions"
println("Before Swapping String values are: \(str1) and \(str2)")
exchange(&str1, &str2)
println("After Swapping String values are: \(str1) and \(str2)")
Playgroundを使用して上記のプログラムを実行すると、以下の結果が得られます.
Before Swapping Int values are: 100 and 200
After Swapping Int values are: 200 and 100
Before Swapping String values are: Generics and Functions
After Swapping String values are: Functions and Generics
関連タイプSwiftは、関連タイプを許可し、キーワード「typealias」プロトコルによって内部宣言を定義できます.
protocol Container {
typealias ItemType
mutating func append(item: ItemType)
var count: Int { get }
subscript(i: Int) -> ItemType { get }
}
struct TOS: Container {
// original Stack 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()
tos.push("Swift")
println(tos.items)
tos.push("Generics")
println(tos.items)
tos.push("Type Parameters")
println(tos.items)
tos.push("Naming Type Parameters")
println(tos.items)
Playgroundを使用して上記のプログラムを実行すると、以下の結果が得られます.
[Swift]
[Swift, Generics]
[Swift, Generics, Type Parameters]
[Swift, Generics, Type Parameters, Naming Type Parameters]
Where句タイプ制約を使用すると、汎用関数またはタイプに関連付けられたタイプのパラメータ要件を定義できます.関連するタイプを定義する「where」句は、タイプパラメータリストの一部の要件として宣言されます.「where」キーワードタイプパラメータの後ろのタイプと関連タイプの間の関連タイプの制限、平等関係のリストの後に配置されます.
protocol Container {
typealias ItemType
mutating func append(item: ItemType)
var count: Int { get }
subscript(i: Int) -> ItemType { get }
}
struct Stack: Container {
// original Stack 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 {
// check that both containers contain the same number of items
if someContainer.count != anotherContainer.count {
return false
}
// check each pair of items to see if they are equivalent
for i in 0.. if someContainer[i] != anotherContainer[i] {
return false
}
}
// all items match, so return true
return true
}
var tos = Stack()
tos.push("Swift")
println(tos.items)
tos.push("Generics")
println(tos.items)
tos.push("Where Clause")
println(tos.items)
var eos = ["Swift", "Generics", "Where Clause"]
println(eos)
Playgroundを使用して上記のプログラムを実行すると、以下の結果が得られます.
[Swift]
[Swift, Generics]
[Swift, Generics, Where Clause]
[Swift, Generics, Where Clause]