Swift初见(一)

  Swift是一种安全快速互动的编程语言,将现代编程语言的精华和苹果工程师文化的智慧,以及来自开源社区的多样化共享结合了起来。对于初学者的表达力也很友好。是一门满足工业标准,但又有脚本语言表达力可玩性支持代码预览,可以让程序员在不编译和运行程序的前提下运行Swift代码实时查看结果
通过采用现代编程模式来避免大量常见编程错误:

  • 变量始终在使用前初始化
  • 检查数组索引超出范围的错误
  • 检查整数是否溢出
  • 可选值确保明确处理nil
  • 内存自动管理
  • 错误处理允许从意外故障控制恢复

简单值

  • 使用let来声明常量,使用var来声明变量
var myNumber = 42
myNumber = 50
let myConstant = 42
  • 不同类型的值不能一起相互拼接
// 编译器会自动推断其类型
let label = "The width is "
let width = 94
let aa = 4.95

// 错误
let widthLabel = label + width
let bb = width + aa

// 正确
let widthLabel = label + String(width)
let bb = width + Int(aa)
  • \()其他类型转为字符串
let apples = 3
let oranges = 5
let appleSummary = "I have \(apples) apples."
let fruitSummary = "I have \(apples + oranges) pieces of fruit."
  • """包含多行字符串内容,
 let apples = 3
 let oranges = 5
 let quotation = """
I said "I have \(apples) apples."
And then I said "I have \(apples + oranges) pieces of fruit."
"""
  • []创建空数组[:]创建空字典,并使用下标或者来访问元素,
var shoppingList = ["catfish", "water", "tulips", "blue paint"]
shoppingList[1] = "bottle of water"

var occupations = [
    "Malcolm": "Captain",
    "Kaylee": "Mechanic",
]
occupations["Jayne"] = "Public Relations"

//空数组和空字典,字典是一个无序的集合
shoppingList = []
occupations = [:]
  • append添加元素
shoppingList.append("blue paint")
print(shoppingList)

控制流

  • 使用ifswitch来进行条件操作
// if
let score = 80
if score > 60 {
   print("及格")
} else {
   print("不及格")
}
*************************************
// switch 匹配到case语句之后,程序会退出switch语句,不会继续向下运行,所以不需要在每个子句结尾写break
let vegetable = "red pepper"
switch vegetable {
case "celery":
    print("Add some raisins and make ants on a log.")
case "cucumber", "watercress":
    print("That would make a good tea sandwich.")
case let x where x.hasSuffix("pepper"):
    print("Is it a spicy \(x)?")
default:
    print("Everything tastes good in soup.")
}
  • 使用for-inwhilerepeat-while来进行循环
// for-in
let individualScores = [75, 43, 103, 87, 12]
var teamScore = 0
for score in individualScores {
    if score > 50 {
        teamScore += 3
    } else {
        teamScore += 1
    }
}
print(teamScore)

// 在for-in中可以使用"..<"来表示下标范围(不包含上界,如果想包含的话使用"...")
var total = 0
for i in 0..<4 {
    total += i
}
print(total)
*************************************

// while
var n = 2
while n < 100 {
    n *= 2
}
print(n)
*************************************

// repeat-while
var m = 2
repeat {
    m *= 2
} while m < 100
print(m)

函数和闭包

  • 使用func来声明一个函数,使用名字和参数来调用函数。使用->来指定函数返回值的类型
func greet(person: String, day: String) -> String {
    return "Hello \(person), today is \(day)."
}
greet(person:"Bob", day: "Tuesday")
  • 使用元组来生成复合值,该元组的元素可以用名字数字来获取
func calculateStatistics(scores: [Int]) -> (min: Int, max: Int, sum: Int) {
    var min = scores[0]
    var max = scores[0]
    var sum = 0

    for score in scores {
        if score > max {
            max = score
        } else if score < min {
            min = score
        }
        sum += score
    }

    return (min, max, sum)
}
let statistics = calculateStatistics(scores:[5, 3, 100, 3, 9])

//获取元组的元素
print(statistics.sum)
print(statistics.2)
  • 函数可以嵌套,一般用来重构一个太长或者太复杂的函数
func returnFifteen() -> Int {
    var y = 10
    func add() {
        y += 5
    }
    add()
    return y
}
returnFifteen()
  • 函数是第一等类型,这意味着函数可以作为另一个函数的返回值
func makeIncrementer() -> ((Int) -> Int) {
    func addOne(number: Int) -> Int {
        return 1 + number
    }
    return addOne
}
var increment = makeIncrementer()
increment(7)

  看到这里是不是有点懵逼((Int) -> Int)这句呢?((Int) -> Int)表示一个闭包(或函数),接受一个Int参数并返回一个Int。其实你可以这么想,var increment = makeIncrementer()这个拿到了addOne这个函数,然后addOne需要一个为Int类型的参数,所以前面那个(Int)指的是addOne的参数。

  • 函数也可以当作参数传入另一个函数
func hasAnyMatches(list: [Int], condition: (Int) -> Bool) -> Bool {
    for item in list {
        if condition(item) {
            return true
        }
    }
    return false
}
func lessThanTen(number: Int) -> Bool {
    return number < 10
}
var numbers = [20, 19, 7, 12]
hasAnyMatches(list: numbers, condition: lessThanTen)

对象和类

使用class类名来创建一个类。类中的属性的声明和我们之前看到常量、变量的声明一样,唯一区别是它们的上下文是

class Shape {
    var numberOfSides = 0
    func simpleDescription() -> String {
        return "A shape with \(numberOfSides) sides."
    }
}
  • 访问
var shape = Shape()
shape.numberOfSides = 7
var shapeDescription = shape.simpleDescription()
  • init构造器
class NamedShape {
    var numberOfSides: Int = 0
    var name: String

    init(name: String) {
        self.name = name
    }

    func simpleDescription() -> String {
        return "A shape with \(numberOfSides) sides."
    }
}

// 调用
let shape = NamedShape(name: "测试")
shape.numberOfSides = 11
print(shape.simpleDescription())

  这里我们用init来创建一个构造器,这样你创建实例的时候,像传入函数参数一样给类传入构造器的参数

  • deinit析构器
deinit {
     print("析构器")
 }

  与init相对应,通常你不需要使用deinit,当你的实例化对象不在使用时,系统会自动帮你管理内存,如果你需要在对象释放之前进行一些清理工作的话,那么就可以使用deinit创建一个析构函数。

  • override,子类如果重写父类的方法的话,需要用这个标记,不然会报错
class Square: NamedShape {
    var sideLength: Double

    init(sideLength: Double, name: String) {
        self.sideLength = sideLength
        super.init(name: name)
        numberOfSides = 4
    }

    func area() ->  Double {
        return sideLength * sideLength
    }

    override func simpleDescription() -> String {
        return "A square with sides of length \(sideLength)."
    }
}
let test = Square(sideLength: 5.2, name: "my test square")
test.area()
test.simpleDescription()
  • getset
var perimeter: Double {
        get {
            return 3.0 * sideLength
        }
        set {
            sideLength = newValue / 3.0
        }
    }

  我们这里是声明属性perimeter,然后perimetersetter中,新值的名字是newValue(🌰:xxx.perimeter=1010)

  • willSetdidSet这两个叫做属性观察器,当你不需要计算属性,但是仍然需要设置一个新值之前或者之后运行代码的时候使用
class aaa {
    var bbb: Int = 0 {
        willSet(newA) {
            print ("new is \(newA)" )
        }   
        
        didSet {
            if bbb > oldValue {     // oldValue是系统层面定义的 对旧值的标签名,不用提前声明,可以直接用。
                print("increase \(bbb - oldValue)")
            } else {
                print("new bbb is small than oldValue")
            }
        }
    } 
}

枚举和结构体

  • 使用enum来创建一个枚举,可以包含方法
enum Rank: Int {
        case ace = 1
        case two, three, four, five, six, seven, eight, nine, ten
        case jack, queen, king
        func simpleDescription() -> String {
            switch self {
            case .ace:
                return "ace"
            case .jack:
                return "jack"
            case .queen:
                return "queen"
            case .king:
                return "king"
            default:
                return String(self.rawValue)
            }
        }
    }

// 调用
let ace = Rank.ace
let aceRawValue = ace.rawValue

  默认情况下,Swift按照从0开始每次加1的方式为原始值进行赋值,这里我们给ace = 1进行改变,使其从1开始。使用rawValue属性来访问一个枚举成员的原始值。

  • 使用struct来创建一个结构体,结构体和类有很多相同的方法,包括方法和构造器,最大区别是:结构体是传值,类是传引用
struct Card {
    var rank: Rank
    func simpleDescription() -> String {
        return "The \(rank.simpleDescription()) of aaa"
    }
}

//调用
let threeOfSpades = Card(rank: .three)
let threeOfSpadesDescription = threeOfSpades.simpleDescription()

协议和扩展

  • 使用protocol来声明一个协议
protocol ExampleProtocol {
    var simpleDescription: String { get }
    mutating func adjust()
}
  • 类、枚举和结构体都可以遵循协议
// 类
class SimpleClass: ExampleProtocol {
    var simpleDescription: String = "A very simple class."
    var anotherProperty: Int = 69105
    func adjust() {
        simpleDescription += "  Now 100% adjusted."
    }
}
var a = SimpleClass()
a.adjust()
let aDescription = a.simpleDescription

// 结构体
struct SimpleStructure: ExampleProtocol {
    var simpleDescription: String = "A simple structure"
    mutating func adjust() {
        simpleDescription += " (adjusted)"
    }
}
var b = SimpleStructure()
b.adjust()
let bDescription = b.simpleDescription

mutating关键字用来标记一个会修改结构体的方法

  • 使用 extension 来为现有的类型添加功能,比如新的方法计算属性
extension Int: ExampleProtocol {
    var simpleDescription: String {
        return "The number \(self)"
    }
    mutating func adjust() {
        self += 42
    }
}
print(7.simpleDescription)

未完待续.....

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

推荐阅读更多精彩内容

  • 前言:本篇文章的目的,在于记录学习过程,敦促自己,方便查看。练习工具:Playground学习网站: swift...
    麦穗0615阅读 1,208评论 1 3
  • swift是一门什么语言了? swift语言是苹果2014年6月3日正式推出一门新的的语言。swift语言主...
    在伦敦涂鸦阅读 361评论 0 2
  • 变量和常量 任何 Swift 中的变量要么不变的,要么是可变的。这句话可不要和 Int、 Float 这些变量类型...
    寥寥十一阅读 192评论 0 1
  • https://docs.swift.org/swift-book/GuidedTour/GuidedTour.h...
    zheNgHH阅读 413评论 0 0
  • 苹果官方最新的《The Swift Language》和《Using Swift with Cocoa and O...
    iOS开发之家阅读 386评论 0 4