Swift所有关键字和基本数据类型

1、数值类型

swift基本数据类型
Int、UInt、Float、Double、Bool、String、Character、Optional、Dictionay、Set、Array、Any、AnyObject
swift的基本数据类型都是struct类型。赋值给另一个变量的时候会复制一份相同的内容给另外一个变量。

title content
值类型(value type) 1、枚举(enum):Optional
2、结构体 (truct):Bool、Int、Float、Double、Character、String、Array、Dictioanry、Set
引用类型(reference type) 类(class)

1、String字符串

// 初始化
var str = "Swift"
var str = String("Swift")
// 字符串连接
var str2 = "OC"
var str3 = str+str2
// 字符串比较
if str == str2 {
    print( "\(str) 与 \(str2) 是相等的" )
} else {
    print( "\(str) 与 \(str2) 不相等" )
}

2、Character为字符修饰的类型为单个字母

// Character只能取单个字母,不能为空否则会crash
for ch in "Swift" { // 遍历字符
    print(ch)
}

3、Optional为可选类型,一般可以用?代替

let rows: Optional<Int>
let rows: Int? // 表明rows可能是Int,也可能是nil,使用的时候使用!取值
// ?和!的区别
// ?是一种判断后再拆包的语法糖,当你不确定有值的时候就可以用 “?”
// !是一种强制拆包的语法糖,当你确定有值的时候可以用 “!”

4、Dictionary字典类似于OC的NSDictionary

// 创建
var dic = Dictionary<Int, String>()
var dic = [Int:String]()
var dic:[Int:String] = [1:"One", 2:"Two", 3:"Three"]
// 取值
var oneVar = dic  // 默认取第一个
var twoVar = dic[2]
let keys = dic.keys // 取出来为数组
let values = dic.values

for (key, value) in dic.enumerated() {
    print("字典 key \(key) -  字典 (key, value) 对 \(value)")
}
for item in dic {
    print("\(item.key) --> \(item.value)")
}
// 修改
var newOneVar = dic.updateValue("new One", forKey: 1)
dic[1] = "new One"
// 移除
var removedValue = dic.removeValue(forKey: 2)
dic[2] = nil
let index = dic.index(dic.startIndex, offsetBy: 1) 
dic.remove(at: index) // 通过下标移除
dic.removeAll()  // 移除所有
// 其他属性
print("dic 含有 \(dic.count) 个键值对") // 计算个数
print("dic = \(dic.isEmpty)")         // 判空

5、Set集合类似于OC的NSSet

// 创建
var s = Set<String>()
var s: Set<String> = ["One", "Two", "Three"]
// 取值
for num in s.sorted() {
    print("\(num)")
}
// 添加
s.insert("Four")
// 删除
if let removeFour = s.remove("Four") {
    print("\(removeFour)? I'm over it.")
} else {
    print("removeFour error")
}
// 其他
if s.contains("Four") {
    print("s contain Four")
} else {
    print("s not contain Four")
}
if s.isEmpty {
    print("s集合为空.")
} else {
    print("s集合不为空.")
}
// union、intersection、subtracting、symmetricDifference
// isSubset(of:)、isSuperset(of:)、isStrictSubset(of:)、isStrictSuperset(of:)、isDisjoint(with:)

6、Array数组类似于OC的NSArray

// 创建
var arr = Array<String>()
var arr = [String](repeating: "Zero', count: 1)
var arr:[String] = ["One", "Two", "Three"]
// 取值
var oneVar = arr[0]
var twoVar = arr.index(after: 0)
var oneVar = arr.index(before: 1)
// 修改
arr[0] = "newOne"
// 添加
arr.append("Four")
arr += ["Five"] // 合并数组
// 删除
arr.remove(at: 4)
arr.removeAll()
// 其他
print("arr.isEmpty = \(arr.isEmpty)")

7、Any可以表示任意类型,甚至包括函数类型,类似于OC的id

AnyObject可以表示任意类型的实例,使用class定义的对象

2、关键字

声明的关键字
class、deinit、init、enum、extension、func、import、let、var、operator、protocol、static、struct、typealias、open、public、internal、fileprivate、private、subscript、
语句中的关键字noescape
fallthrough、defer、break、case、default、do、else、for、guard、if、in、repeat、return、switch、where、while
表达式和类型的关键字
try、as、catch、throw、throws、rethrows、false、is、nil、super、Self、self、true
特定上下文中被保留的关键字
associatedtype、some、convenience、dynamic、optional、protocol、final、infix、prefix、postfix、lazy、indirect、mutating、none、nonmutating、override、precedencegroup、required、get、set、unowned、weak、inline、@discardableResult

1、deinit和init,convenience(便利构造器)

init指定构造器(init?、init!可失败构造器)
convenience便利构造器必须调用init方法、也可以在extension中调用init方法
deinit析构函数

class People {
    var name: String
    init(name: String) { // 指定构造器
        self.name = name
    }
    init?(name: String) { // 可失败构造器
        self.name = name
        if name.isEmpty { return nil }
    }
    deinit {
        // 执行析构过程
    }
}
extension People {
    convenience init(smallName: String) {// 便利构造器
        self.init(name: smallName)
    }
}

2、enum枚举

// 枚举相关值基本用法
enum Student {
    case Name(String)
    case Score(Int,Int,Int)
}
var name = Student.Name("Swift")
var score = Student.Score(98,97,95)
switch score {
    case .Name(let studName):
        print("学生的名字是: \(studName)。")
    case .Mark(let score1, let score2, let score3):
        print("学生的成绩是: \(score1),\(score2),\(score3)。")
}

3、extension和oc的category功能大同小异,区别是swift的扩展方法可以被外部类调用,也支持被继承。

4、let和var的区别,let为常量,var为变量。

5、operator 自定义运输符

// prefix 前置运输符号
// infix 中间运输符号
// postfix 后置运输符号
prefix operator  ^
prefix func ^ (var vector: Double) -> Double {
    return pow(2, vector)
}
print(^5)
// 
postfix operator  ^
postfix func ^ (var vector: Int) -> Int {
    return vector * vector
}
print(5^)

// precedencegroup 优先级
infix operator ^^:Precedence
precedencegroup Precedence {
    associativity: left // 结合性 none
    higherThan: AdditionPrecedence    // 比加法高
    lowerThan: MultiplicationPrecedence  // 比乘法低
    assignment: true // 代表在可选链操作中拥有跟赋值运算符一样的优先级
}
func ^^(left: Double, right: Double) -> Double {
    return pow(left, right)
}
print(2 ^^ 10 - 2 ^^ 3) 

6、open、public、internal、fileprivate、private访问控制

open 可以被其他module中继承重写
public 只能在其他module中调用,不能重写
internal 只能在内部module中调用重写
fileprivate 能在相同的文件中调用
private 只能在类的内部使用

7、subscript下标脚本

// 动态成员查找
@dynamicMemberLookup // 标记使用的subscript有自定义值
struct Person {
    subscript(dynamicMember member: String) -> String {
        let properties = ["nickname": "Zhuo", "city": "Hangzhou"]
        return properties[member, default: "undefined"]
    }
}
//执行以下代码
let p = Person()
print(p.city)
print(p.nickname)
print(p.name)
// 扩展 
// dynamicCallable 函数变量可以作为函数调用
@dynamicCallable
struct RandomNumberGenerator {
    func dynamicallyCall(withArguments args: [Int]) -> Double {
        let numberOfZeroes = Double(args.first ?? 0)
        let maximum = pow(10, numberOfZeroes)
        return Double.random(in: 0...maximum)
    }
}
// 调用方式
let random = RandomNumberGenerator()
let num = random(2)
// random(2)等同于random.dynamicallyCall(withArguments: [2])
print(num)

8、fallthrough 在swich语句中继续往后执行跑一个case

let Describe = 1
var description = "The number \(Describe) is"
    switch Describe {
    case 1,3,7:
        description += " a prime number, and also"
        fallthrough
    case 5:
        description += " an integer"
    default :
        description += " finished"
}
print(description)

9、defer 在{}作用域的最后一行执行defer

defer {
  print("finally")
}
do {
  throw NSError()
  print("impossible")
} catch {
  print("handle error")
}

10、for 循环使用

// forEach的使用
let arr: [String] = ["One","Two","Three"]
arr.forEach { (item) in
    print("\(item)")
}
// for循环100次
for _ in 0...100 {
    print("good");
}

11、guard和if相反,guard是条件不满足的情况下执行

// if 的作用域只在当前的if条件语句内
func login(_ info: [String: String]) {
  var username
  if let tmp = info["username"] {
    username = tmp
    print("请输入用户名")
    return
  }
  print("用户名:\(username)")
}
// guard的作用域在当前guard所在大括号内,且guard执行完成之后必须退出当前作用域
func login(_ info: [String: String]) {
  guard let username = info["username"] else {
    print("请输入用户名")
    return
  }
  print("用户名:\(username)")
}

12、repeat 先判断条件语句后循环

repeat{
    print( "index 的值为 \(index)")
    index = index + 1
}while (index < 20)

13、where 条件语句

//协议
protocol aProtocol{}
extension aProtocol where Self:UIView{
    //只给遵守aProtocol协议的UIView添加了拓展
    func getString() -> String{
        return "string"
    }
}

//使用for in遍历
for value in array where value > 2 {
    print(value)   //输出3 4 5 6
}

14、as类型转换

let money = 20 as CGFloat // 转换为CGFloat类型

15、is 若一个类属于另一个类的子类,则会返回true,否则返回false。

class Person {}
class Student:Person {}
let s = Student()
if s is Person {
    print("Student")
}

16、try、catch、throw、throws、rethrows

throw 抛出一个错误允许你明确某些意外的事情发生了并且正常的执行流不能继续下去。
throws 函数内部通过throw抛出自定义Error,可能会抛出Error的函数必须加上throws声明
rethrows 函数本身不会抛出错误,但调用闭包参数抛出错误,那么它会将错误向上抛。

enum SomeError : Error {
    case illegalArg(String)
    case outOfBounds(Int, Int)
    case outOfMemory
}

func divide(_ num1: Int, _ num2: Int) throws -> Int {
    if num2 == 0 {
        throw SomeError.illegalArg("0不能作为除数")
    }
    return num1 / num2
}
func exec(_ fn: (Int, Int) throws -> Int, _ num1: Int, _ num2: Int) rethrows {
    print(try fn(num1, num2))
}
try exec(divide, 20, 0)

17、Self和self

1、self和oc的用法一样
2、Self 1)、可以用于协议中限制相关类型。2)、可以用于类中充当方法的返回值。3)可以访问静态方法或变量
3、.self类型的本身值。Class.self返回当前类的元类信息。

protocol Copyable {
    func copy() -> Self
    func clamp(intervalToClamp: Self) -> Self
}
class A: Copyable {
    var num = 1
    required init() {}
    func copy() -> Self {
        let result = self
        result.num = num
        return result
    }
    func clamp(intervalToClamp: A) -> Self {
        let result = self
        result.num = num
        return result
    }
    class func calssFunc() -> Self {
        let type = self
        print(type)
        let result = type.init()
        return result
    }
}

class B: A {
    func clamp(intervalToClamp: B) -> Self {
        let result = self
        result.num = num
        return result
    }
}

let type = A.self // A.self代表元类
type.calssFunc()

let typeB = B.self
typeB.calssFunc()

let objectA = A()
objectA.num = 100

let newObjectA = objectA.copy()
objectA.num = 1

let objectB = B()
objectB.num = 100
let newB = objectB.copy()

18、associatedtype 关联类型,为协议中的某个类型提供占位符。some指明返回的协议为不透明类型,明确为某一种类型。

protocol NetworkRequest {
    associatedtype T
    func didReceiveData(_ data: T)
}
class ViewModel: NetworkRequest {
    typealias T = String
    func didReceiveData(_ data: T) {
    }
}
class PresetModel: NetworkRequest {
     func didReceiveData(_ data: T) {
     }
}
// 函数的返回需要some指明,只能返回某一种类型
func requestType() -> some NetworkRequest {
    return ViewModel()
}

19、convenience 便利构造器

class MainClass {
    var name: String
    init(name: String) {
        self.name = name
    }
    convenience init() {
        self.init(name: "[匿名]")
    }
    // 类里面使用懒加载
    lazy var planNameLabel: UILabel = {
        let label = UILabel()
        label.text = "yo yo yo kongfu!"
        return label
    }()
}
let main = MainClass(name: "Runoob")
print("MainClass 名字为: \(main.name)")

let main2 = MainClass()
print("没有对应名字: \(main2.name)")

20、dynamic,swift调用的方法具有oc的动态性能,optional标记oc协议为可选值

@objc protocol CounterDataSource {
    @objc optional var fixedIncrement: Int { get }
    @objc optional func incrementForCount() -> Int
    dynamic func decrementForCount() -> Int
}

21、final,类方法属性等不希望被重写或者继承时,在前面添加的标记

22、lazy 懒加载

// 懒加载打印序列
let numbers = 1...5
let doubleNumbers = numbers.lazy.map { (i: Int) -> Int in
    print("numbers\(i)")
    return i * 2
}
for i in doubleNumbers {
    print("doubleNumbers\(i)")
}
// 懒加载UILabel
var planNameLabel: UILabel = {
    let label = UILabel()
    label.text = "lazy OK!"
    return label
}()

23、indirect 递归枚举,枚举值中包含自己的枚举

indirect enum ArithExpr {
    case number(Int)
    case sum(ArithExpr, ArithExpr)
    case difference(ArithExpr, ArithExpr)
}

let five = ArithExpr.number(5)
let four = ArithExpr.number(4)
let two = ArithExpr.number(2)
let sum = ArithExpr.sum(five, four)
let difference = ArithExpr.difference(sum, two)

24、mutating 结构体和枚举类型值默认情况下是不能被修改,如果要修改加上关键字mutating

protocol Togglable {
    mutating func toggle()
}
struct Test: Togglable {
    var time: Int = 0
    mutating func toggle() {
        self.time = 33333
    }
}
var test = Test()
test.time = 2
print(test.time)
test.toggle()
print(test.time)

25、unowned、weak,无主引用和弱引用的区别,弱引用必须为可选类型,当引用的对象不存在时,自动设置为nil;无主引用不能为可选类型,如果引用了一个已经被销毁的对象会抛出错误。

let var Optional Non-Optional
strong
weak
unowned
class User {
    var name: String
    private(set) var phones: [Phone] = []
    // 使用的运营商
    var subscriptions: [CarrierSubscription] = []
    
    init(name: String) {
        self.name = name
        print("初始化 \(name)")
    }
    
    func addPhone(phone: Phone) {
        phones.append(phone)
        // 手机的持有者
        phone.owner = self
    }
    deinit {
        print("销毁 \(name)")
    }
}

class Phone {
    let model: String
    weak var owner: User?
    var carrierSubscription: CarrierSubscription?
    init(model: String) {
        self.model = model
        print("手机模型 \(model)")
    }
    func provision(carrierSubscription: CarrierSubscription) {
        self.carrierSubscription = carrierSubscription
    }
    
    func decommission() {
        self.carrierSubscription = nil
    }
    
    deinit {
        print("销毁手机模型 \(model)")
    }
}

class CarrierSubscription {
    let name: String
    let countryCode: String
    let number: String
    let user: User
    init(name: String, countryCode: String, number: String, user: User) {
        // 运营商名
        self.name = name
        // 区号
        self.countryCode = countryCode
        // 电话号码
        self.number = number
        // 对应用户
        self.user = user
        // 将 CarrierSubscription 添加到User的subscriptions属性中
        user.subscriptions.append(self)
        print("CarrierSubscription \(name) 初始化")
    }
    deinit {
        print("CarrierSubscription \(name) 销毁")
    }
}

do {
  unowned let user = User(name: "John")
  let iphone = Phone(model: "iphone6s")
  user.addPhone(phone: iphone)
  let subscription = CarrierSubscription(
        name: "TelBel",
        countryCode: "0032",
        number: "31415926",
        user: user)
  iphone.provision(carrierSubscription: subscription)
}

26、inline内联函数,函数声明前加@inline

// 永远不会被内联(即使开启了编译器优化)
@inline(never) func test() {
    print("test")
}
// 开启了编译器优化后,即使代码很长,也会被内联(递归函数、动态派发的函数除外)
@inline(__always) func test() {
    print("test")
}

27、@discardableResult标记返回值可以不被使用(语法糖)

protocol Togglable {
    mutating func toggle()
}
struct Test: Togglable {
    var time: Int = 0
    @discardableResult mutating func toggle() {
        self.time = 33333
        return self.time // 有返回值
    }
}
var test = Test()
test.toggle() // 可以不使用返回值,无警告
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,951评论 6 497
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,606评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 160,601评论 0 350
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,478评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,565评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,587评论 1 293
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,590评论 3 414
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,337评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,785评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,096评论 2 330
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,273评论 1 344
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,935评论 5 339
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,578评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,199评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,440评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,163评论 2 366
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,133评论 2 352

推荐阅读更多精彩内容