Swift知识点(四)

16. 内存访问冲突、指针

局部作用域

可以使用do实现局部作用域在这里插入图片描述
这样直接写局部变量会报错
加上do,即可实现局部变量

do {
   
   
    int a = 10
}

内存访问冲突

内存访问冲突会在两个访问满足下列条件时发生:

  • 至少一个是写入操作
  • 它们访问的是同一块内存
  • 它们的访问时间重叠(比如在同一个函数内)

指针

Swift中有专门的指针类型,被定性为“Unsafe”(不安全的),常见的有以下4种类型

  • UnsafePointer<Pointee> 类似于 const Pointee *
  • UnsafeMutablePointer<Pointee> 类似于 Pointee *
  • UnsafeRawPointer<Pointee> 类似于 const void *
  • UnsafeMutableRawPointer<Pointee> 类似于 void *

第一个,只可以访问指针,不可以修改指针
第二个,可以访问和修改指针
<Pointee>泛型,如果是Int,说明只能访问Int类型的指针

var age = 10

func test1(_ ptr: UnsafeMutablePointer<Int>){
   
   
    //取数的时候,直接使用ptr.pointee即可(不用*ptr)
    //由于是mutable,可以修改
    ptr.pointee = 20
    print("test1", ptr.pointee)
}

func test2(_ ptr: UnsafePointer<Int>){
   
   
    print("test2", ptr.pointee)
}

test2(&age)
test1(&age)
print(age)

结果:
test2 10
test1 20
20

17. 字面量协议、模式匹配、条件编译

字面量(Literal)

var age = 10
var isRed = false
var name = "Jack"

上面代码中:10、false、"Jack"就是字面量

可以看到,初始化过程很简单,直接赋值即可

Swift自带的绝大部分类型,都支持直接通过字面量进行初始化

而,当是一个对象的时候,却需要使用下面方法去初始化:

var p = Person()
var p = Person.init()
问:为何自带类型可以直接初始化?而对象却不可以?

是因为Swift自带类型,遵守了对应的 字面量协议

在这里插入图片描述

var num: Int = true
当直接写上述代码时,是错误的❌
因为,把bool值类型,赋值给了int类型,类型不匹配

但,当做下列操作,即可变为编译正确

//extension扩展协议
//Int类型遵守ExpressibleByBooleanLiteral协议
extension Int: ExpressibleByBooleanLiteral{
   
   
	//协议要实现的方法
    public init(booleanLiteral value: BooleanLiteralType) {
   
   
        self = value ? 1 : 0
    }
}

var num: Int = true
print(num)

var num2: Int = 100
print(num2)

1
100

在扩展中添加协议成员
我们可以通过扩展来扩充已存在类型( 类,结构体,枚举等)。
扩展可以为已存在的类型添加属性,方法,下标脚本,协议等成员。

其中:

//ExpressibleByBooleanLiteral是一个协议
public protocol ExpressibleByBooleanLiteral {
   
   
    associatedtype BooleanLiteralType : _ExpressibleByBuiltinBooleanLiteral
    //协议要实现的方法
    init(booleanLiteral value: Self.BooleanLiteralType)
}
作业:
var num: Int? = Int("123")
print(num)//123

var num2: Int? = Int("fff")
print(num2)//nil

扩展出:

var num: Int? = "123"
print(num)//123

var num2: Int? = "fff"
print(num2)//nil或0

参考答案:

extension Int: ExpressibleByStringLiteral
{
   
   
    public init(stringLiteral value: String) {
   
   
        self = (Int(value) != nil ? Int(value)! : 0)
    }
}


var num: Int? = "123"
print(num)

var num2: Int? = "fff"
print(num2)

模式(Pattern)

什么是模式?
模式是用于匹配的规则,比如switch的case、捕捉错误的catch、if\guard\while\for语句 的条件等

let age = 2
if case 0...9 = age {
   
   
    print("in")
}

相当于switch写法

switch age{
   
   
    case 0...9:
        print("in")
    default:break
}

也就是,if case相当于只有一个case的switch

for case let
let points = [(1, 0), (2, 1), (3, 0)]
for case let(x, 0) in points{
   
   
    print(x)
}
//1
//3
let ages: [Int?] = [nil, 2, 3, nil, 5]
for case let age? in ages {
   
   
    print(age)
}
等价于:
for item in ages {
   
   
    if let age = item {
   
   
        print(age)
    
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值