swift菜鸟教程29-30(泛型,访问控制)

一个朴实无华的目录

今日学习内容:

1.Swift 泛型

1.1泛型类型

swift 复制代码
// 定义一个交换两个变量的函数
func swapTwoValues<T>(_ a: inout T, _ b: inout T) {
    let temporaryA = a
    a = b
    b = temporaryA
}
 
var numb1 = 100
var numb2 = 200
 
print("交换前数据:  \(numb1) 和 \(numb2)")
swapTwoValues(&numb1, &numb2)
print("交换后数据: \(numb1) 和 \(numb2)")
 
var str1 = "A"
var str2 = "B"
 
print("交换前数据:  \(str1) 和 \(str2)")
swapTwoValues(&str1, &str2)
print("交换后数据: \(str1) 和 \(str2)")

Stack 基本上和 IntStack 相同,占位类型参数 Element 代替了实际的 Int 类型。

以上实例中 Element 在如下三个地方被用作占位符:

创建 items 属性,使用 Element 类型的空数组对其进行初始化。

指定 push(_😃 方法的唯一参数 item 的类型必须是 Element 类型。

指定 pop() 方法的返回值类型必须是 Element 类型。

swift 复制代码
struct Stack<Element> {
    var items = [Element]()
    mutating func push(_ item: Element) {
        items.append(item)
    }
    mutating func pop() -> Element {
        return items.removeLast()
    }
}
 
var stackOfStrings = Stack<String>()
print("字符串元素入栈: ")
stackOfStrings.push("google")
stackOfStrings.push("runoob")
print(stackOfStrings.items);
 
let deletetos = stackOfStrings.pop()
print("出栈元素: " + deletetos)
 
var stackOfInts = Stack<Int>()
print("整数元素入栈: ")
stackOfInts.push(1)
stackOfInts.push(2)
print(stackOfInts.items);

1.2扩展泛型类型

为其添加了一个名为 topItem 的只读计算型属性,它将会返回当前栈顶端的元素而不会将其从栈中移除:

swift 复制代码
struct Stack<Element> {
    var items = [Element]()
    mutating func push(_ item: Element) {
        items.append(item)
    }
    mutating func pop() -> Element {
        return items.removeLast()
    }
}
 
extension Stack {
    var topItem: Element? {
       return items.isEmpty ? nil : items[items.count - 1]
    }
}
 
var stackOfStrings = Stack<String>()
print("字符串元素入栈: ")
stackOfStrings.push("google")
stackOfStrings.push("runoob")
 
if let topItem = stackOfStrings.topItem {
    print("栈中的顶部元素是:\(topItem).")
}
 
print(stackOfStrings.items)
实例中 topItem 属性会返回一个 Element 类型的可选值。当栈为空的时候,topItem 会返回 nil;当栈不为空的时候,topItem 会返回 items 数组中的最后一个元素。

以上程序执行输出结果为:

字符串元素入栈: 
栈中的顶部元素是:runoob.
["google", "runoob"]

1.3类型约束

swift 复制代码
// 非泛型函数,查找指定字符串在数组中的索引
func findIndex(ofString valueToFind: String, in array: [String]) -> Int? {
    for (index, value) in array.enumerated() {
        if value == valueToFind {
            // 找到返回索引值
            return index
        }
    }
    return nil
}
 
 
let strings = ["google", "weibo", "taobao", "runoob", "facebook"]
if let foundIndex = findIndex(ofString: "runoob", in: strings) {
    print("runoob 的索引为 \(foundIndex)")
}

1.4关联类

swift 复制代码
// Container 协议
protocol Container {
    associatedtype ItemType
    // 添加一个新元素到容器里
    mutating func append(_ item: ItemType)
    // 获取容器中元素的数
    var count: Int { get }
    // 通过索引值类型为 Int 的下标检索到容器中的每一个元素
    subscript(i: Int) -> ItemType { get }
}

// Stack 结构体遵从 Container 协议
struct Stack<Element>: Container {
    // Stack<Element> 的原始实现部分
    var items = [Element]()
    mutating func push(_ item: Element) {
        items.append(item)
    }
    mutating func pop() -> Element {
        return items.removeLast()
    }
    // Container 协议的实现部分
    mutating func append(_ item: Element) {
        self.push(item)
    }
    var count: Int {
        return items.count
    }
    subscript(i: Int) -> Element {
        return items[i]
    }
}

var tos = Stack<String>()
tos.push("google")
tos.push("runoob")
tos.push("taobao")
// 元素列表
print(tos.items)
// 元素个数
print( tos.count)
以上程序执行输出结果为:

["google", "runoob", "taobao"]
3

1.5Where 语句

swift 复制代码
// 扩展,将 Array 当作 Container 来使用
extension Array: Container {}
 
func allItemsMatch<C1: Container, C2: Container>
    (_ someContainer: C1, _ anotherContainer: C2) -> Bool
    where C1.ItemType == C2.ItemType, C1.ItemType: Equatable {
        
        // 检查两个容器含有相同数量的元素
        if someContainer.count != anotherContainer.count {
            return false
        }
        
        // 检查每一对元素是否相等
        for i in 0..<someContainer.count {
            if someContainer[i] != anotherContainer[i] {
                return false
            }
        }
        
        // 所有元素都匹配,返回 true
        return true
}
var tos = Stack<String>()
tos.push("google")
tos.push("runoob")
tos.push("taobao")
 
var aos = ["google", "runoob", "taobao"]
 
if allItemsMatch(tos, aos) {
    print("匹配所有元素")
} else {
    print("元素不匹配")
}
以上程序执行输出结果为:

匹配所有元素

2.Swift 访问控制

除非有特殊的说明,否则实体都使用默认的访问级别 internal。

2.1语句函数类型访问权限:元组的访问级别与元组中访问级别最低的类型一致子类的

2.2访问级别不得高于父类的访问级别

2.3常量、变量、属性、下标访问权限:不能拥有比它们的类型更高的访问级别。

2.4Setter的访问级别可以低于对应的Getter的访问级别

swift 复制代码
class Samplepgm {
    fileprivate var counter: Int = 0{
        willSet(newTotal){
            print("计数器: \(newTotal)")
        }
        didSet{
            if counter > oldValue {
                print("新增加数量 \(counter - oldValue)")
            }
        }
    }
}
 
let NewCounter = Samplepgm()
NewCounter.counter = 100
NewCounter.counter = 800
counter 的访问级别为 fileprivate,在文件内可以访问。

以上程序执行输出结果为:

计数器: 100
新增加数量 100
计数器: 800
新增加数量 700

2.5构造器和默认构造器访问权限:在每个子类的 init() 方法前使用 required 关键字声明访问权限。

2.6类型别名:任何你定义的类型别名都会被当作不同的类型,以便于进行访问控制。一个类型别名的访问级别不可高于原类型的访问级别。

swift 复制代码
public 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 {
        // 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..<someContainer.count {
            if someContainer[i] != anotherContainer[i] {
                return false
            }
        }
        
        // all items match, so return 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 语句"]
相关推荐
kkkkatoq7 分钟前
设计模式 四、行为设计模式(2)
java·开发语言·设计模式
胡萝卜糊了Ohh1 小时前
scala
开发语言·后端·scala
点纭1 小时前
C 语言 第八章 文件操作
c语言·开发语言
我姓徐2 小时前
C语言-基于AT-SPI无障碍服务操作工具
c语言·开发语言·ui自动化测试·无障碍服务·at-spi
ricky_fan2 小时前
Leetcode39:组合总和——回溯算法
开发语言·c++·leetcode
nainaire2 小时前
学Qt笔记
开发语言·笔记·qt
不爱吃于先生2 小时前
Python基础语法速通(自用笔记)
开发语言·python
向宇it3 小时前
【unity游戏开发介绍之UGUI篇】UGUI概述和基础使用
开发语言·unity·c#·编辑器·游戏引擎
qq_365911603 小时前
探索 MCP 和 A2A 协议: 本质上新协议都基于 HTTP的
开发语言
爱的叹息3 小时前
Java Lambda 表达式详解:发展史、语法、使用场景及代码示例
java·开发语言·python