Swift基础语法

Swift初体验

//1.swift应用程序的入口
@UIApplicationMain
//2.swift中引用框架只需要引入框架的名字
import UIKit
//3.swift引用OC的框架方法名都一样,只是写法不一样
//4.swift类的所有的声名和实现都写在class最外层的大括号里面
//5.重写方法需要加上override
    override func viewDidLoad() {
        super.viewDidLoad()
    }
//6.swift使用点语法调用一个方法
        super.viewDidLoad()
swift单条语句不需要加分号
//var声明一个变量,let声明一个常量
        let firstView = UIView(frame: CGRect(x: 10, y: 30, width: 200, height: 200))

基本数据类型

//: [Previous](@previous)

import Foundation

//基本数据类型
var a:Int = 10
var f:Float = 10.5
var d:Double = 100.5
var t:Bool = true
var fa:Bool = false

//douple元组:可以表示多个值的基本类型
var douple = (a,f)
var a1 = douple.0

var douple2 = (first: a,second: d)
var a2 = douple2.first
var a3 = douple2.0

//运算符
//赋值运算符 =
//算数运算符 + - * / %
//比较运算符 > < >= <= !=
//逻辑运算符 || &&
//三目运算符 ? :

//swift中特殊运算符
//?? 空合运算符
//_ 忽略运算符
//... 区间运算符
//0...5 代表>=0 && <=5



变量和常量

//1.用var来定义一个变量,用let定义一个常量
//变量一旦定义,其值可以改变,常量一旦定义,其值不可以改变
//如果不确定使用let还是var,可以先定义成let.报错时再改回来
var a:Int = 10
a = 5
let a1: Int = 15
//a1 = 20
//2.变量和常量可以根据等号右边的值,自动推导类型
var a3 = 15
let view = UIView()
var f = 10.5 //小数会被默认推断成Double类型
//3.swift对类型的要求极其严格,不同类型不能参与运算
//必须要强转
var result = Double(a3) + f
var result2 = a3 + Int(f)

控制流

//: [Previous](@previous)

import Foundation
//if条件语句的小括号可以省略,执行语句的大括号一定不能省略
var a = 10

if (a > 5) {
    print("hello,world")
}

//使用for in + 区间运算符做循环
//0...10 [0,10]
//0..<10 [0,10)
for i in 0..<10 {
    print(i)
}
//倒序遍历
//从10循环到0
for i in (0...10).reversed() {
    print("love \(i)")
}

//忽略运算符 _:如果不想使用某个值,可以将该值忽略
for _ in 0...5 {
    print("hello")
}

//while
//swift放弃了 ++ 和 -- 运算符
var i = 10
while i > 0 {
    i -= 1
    print("while \(i)")
}

//swift把do while 换成了repeat while
var m = 10
repeat {
    m -= 1
    print("repeat while\(m)")
} while m > 0

//switch
var score = 75
switch score {
case 60,75:
    print("及格")
default:
    print("仍需努力")
}
//可以判断任何类型
var scorestr = "75"
switch scorestr {
case "60":
    print("及格")
default:
    print("仍需努力2")
}
//可以做区间判断
//绑定:定义一个临时的变量或常量,把要判断的值赋值给该变量或常量,后面直接使用这个临时的变量或常量
//where是swift的关键,可以接条件判断语句  
//default 如果case不能覆盖所有条件,则必须加default
//如果多个case同时满足条件,case的条件之间用逗号隔开
switch score {
case let score where score < 60:
    print("不及格")
case let x where x >= 60 && x < 70:
    print("及格")
case let x where x >= 70 && x < 80:
    print("良好")
case let x where x >= 80 && x < 90:
    print("优秀")
case let x where x >= 90:
    print("牛逼")
default:
    print("仍需努力")
}

可选值

//: [Previous](@previous)

import UIKit

//可选值:一个变量或常量,可能有值,可能没有值(nil),一个变量或常量有可能会被设为nil,那么这个值就叫可选值
//对于对象,OC可以将其设为nil
//OC会给变量赋初值,swift不会,swift默认不能将对象设为nil;swift中,如果将对象设为可选值,则任何数据类型都可以设为nil
var view: UIView?
view = nil

//在变量的数据类型后面接一个 ? 代表定义一个可选值
//一旦该变量设为可选,就代表该变量可以设为nil
//对于可选的变量,如果没有初始值,它的初始值为nil
var a:Int?
a = nil
//Optional :可选
var view1: UIView? = UIView()
print(view1)

//可选值不能直接参与运算,需要强制解包,在该值的后面接一个 !
//使用!时,如果该可选值为nil,则会崩溃
//value of optional type 'Int?' not unwrapped;提示使用一个可选值时需要强制解包
//unexpectedly found nil while unwrapping an Optional value 强制解包一个可选值时,发现其值为nil
//? 告诉编译器,我是一个可选值,不要拿我做运算
//! 告诉编译器,我一定有值,可以使用,一旦编译器发现没有值,就会蹦会
var b:Int? = 10
var c:Int? = 10
var result = b! + 10
//如果不确定可选值是否有值,需要先判断是否为nil
//1.直接判断,在使用可选值的时候,仍然需要使用!
if b != nil {
    var result = b! + 10
}
//2.可选绑定
//对于可选值,条件判断语句中,定义一个临时的变量/常量 x,将可选值赋值给x,如果x有值,则绑定成功,后面可以直接使用,如果x没有值,则绑定不成功,可以异常处理;如果需要接条件判断,可以用逗号隔开
//可选绑定,使用可选值最广泛的用法
if let b = b,b > 15 {
    var result = b + 10
}
//对多个可选值做可选绑定
if let b = b,let c = c {
    var result = b + c
}
//可选值的使用
let url = URL(string: "http://www.baidu.com")

let request = URLRequest(url: url!)

if let url = url {
    let request = URLRequest(url: url)
}

空合运算符

var a: Int? = 5
//空合运算符:在使用可选值时,如果可选值有值,则使用可选值的值,如果没有值,则使用空合运算符后面的值
//空合运算符的优先级比算数运算符低
var b = a ?? 10 + 3

字符串

//: [Previous](@previous)

import Foundation

//用var创建一个可变的字符串,用let创建一个不可变的字符串
//自变量创建
var str = "hello"
//构造方法创建
var str2 = String("hello2")
var str3 = String.init("hello3")

//字符串和字符串的拼接
var str4 = "hello,"
var str5 = "world"
var str6 = str4 + str5;
str4 += str5;

//字符串和常量,变量的拼接 \
var classIndex = 5
var str7 = "world"
var str8 = "hello\(str7)"
var str9 = "hello\(classIndex)"

//stringWithFormat
//05:05:05
let h = 5
let m = 5
let s = 5
var time = String(format: "%02d: %02d: %02d", h,m,s)

//字符串的比较
var str10 = "hello"
var str11 = "hello"
var str12 = "helll"
if str10 == str11 {
    print("一样")
}
if str11 != str12 {
    print("不一样")
}

//取字符串的长度
//let count = str12.lengthOfBytes(using: .utf8)
let count = str12.characters.count

//判断是否有前缀
if str12.hasPrefix("h") {
    print("h开头")
}
if str12.hasSuffix("l") {
    print("l结尾")
}
//正常情况下,swift的api可以解决问题,如果解决不了,可以将swift字符串转成oc字符串
let swiftStr = "hello,world"
//as代表类型转换
let ocString = swiftStr as NSString
ocString.substring(with: NSMakeRange(0, 5))

数组

//: [Previous](@previous)

import Foundation


//数组的创建
//用var创建一个可变的数组,用let创建一个不可变的数组
var array = ["dog","cat","pig"]
var emptyArr:[String] = []
array.append("fish")
//用初始化的方式创建数组,一定要指定类型
var array2: [String] = Array()

//数组的遍历
for item in array {
    print(item)
}
//遍历同时拿到index
for item in array.enumerated() {
    print("\(item.offset):\(item.offset)")
}
//倒序遍历
for item in array.reversed() {
    print(item)
}

//数组的操作
//数组的合并
var array3 = ["goat","snake"]
var array4 = ["dog","cat","pig"]
var array5 = array3 + array4
//删除元素
let removed = array5.remove(at: 0)
//修改
array5[0] = "sheep"
//和OC的数组互转
let ocArray = array5 as NSArray
ocArray.subarray(with: NSMakeRange(0, 3))

字典

//: [Previous](@previous)

import Foundation


//定义一个字典
//用var定义一个可变的字典,用let定义一个不可变的字典
var dict = ["first":"dog","second":"cat"]
//定义一个空的字典
var dict1: [String: String] = Dictionary()
var dict2: [String: String] = [:]

//遍历字典
for (k,v) in dict {
    print("key:\(k),value:\(v)")
}
//字典的操作,增删改查,字典的操作都是围绕key值做操作
//增
dict["third"] = "pig"
//删
dict["second"] = nil
//查:从字典中取出的值是一个可选值,使用的时候最好做一次可选绑定
let first = dict["first"]
//改
dict["first"] = "duck"
print(dict)

集合

//: [Previous](@previous)

import UIKit

//let定义不可变集合,var定义可变集合
//无序,不可重复
//空集合
var set: Set<String> = []
var set1: Set<String> = Set()
var Set2 = Set<String>()

//增加元素
set.insert("a")
set.insert("b")
//创建一个带有默认值的集合
let set4: Set = ["cat","dog","cow"]

//集合的遍历
for item in set {
    print(item)
}
//集合中删除一个元素
set.remove("a")
print(set)
//集合的交集,并集的判断
var setaa: Set = [1,2,3,4]
var setbb: Set = [1,2]
var setcc: Set = [3,4,5]
var setdd: Set = [1,2]

if setbb.isSubset(of: setaa) {
    print("bb是aa的子集")
}
if setbb.isStrictSubset(of: setaa) {
    print("bb是aa的真子集")
}
if setbb.isSuperset(of: setdd) {
    print("bb是dd的交集")
}

函数

//: [Previous](@previous)

import Foundation

//用func来创建一个函数
//函数名后面接小括号,小括号不能省略
//小括号里面放参数,参数必须指定类型,多个参数用逗号隔开
//如果没有返回值,返回值的部分可以省略
func add(a:Int,b:Int) -> Int {
   return a + b
}
let funcadd = add

//函数没有返回值,本质上返回一个空的元组
func addOne(a:Int,b:Int){
   print(a + b)
}
func addTwo(a:Int,b:Int) -> (){
   print(a + b)
}
func addThree(a:Int,b:Int) -> Void{
   print(a + b)
}
let funcaddOne = addOne

//没有参数,没有返回值
func methodOne() {
   print("hello,world")
}


//有参数,没有返回值
func methodTwo(a:Int,b:Int) {
   print(a + b)
}
//有参数,有返回值,返回的值和返回值的类型必须保持一致
func methdThird(a:Int,b:Int) -> Int {
   return a + b
}
//函数的调用
methodOne()

外部参数名

//: [Previous](@previous)

import Foundation

//函数的参数默认有一个外部参数名
//外部参数名:就是对参数做解释说明用的字符串
//默认情况下,swift会给每个参数加一个和形参一样的外部参数名
//外部参数名,就是对参数做解释说明的字符串
//外部参数名,在调用的时候,必须写
func add(a: Int,b: Int) {
    return a + b
}
//add(a: <#T##Int#>, b: <#T##Int#>)
//也可以自定义外部参数名
func addOne(first a: Int,second b: Int){
    return a + b
}
//addOne(first: <#T##Int#>, second: <#T##Int#>)

//也可以忽略外部参数名
//使用忽略运算符忽略外部参数名
func addTwo(_ a: Int,_ b: Int) {
    return a + b
}
//addTwo(<#T##a: Int##Int#>, <#T##b: Int##Int#>)

函数默认参数

//: [Previous](@previous)

import UIKit

//swift语言函数的参数可以设默认值
//如果参数有默认值,则该参数可传,可不传
func add(a: Int,b: Int = 10) -> Int {
    return a + b
}

add(a: 5)
add(a: 5, b: 15)

func customLabel(title: String, fontSize: CGFloat = 13,alignment: NSTextAlignment = .left,numberOfLines: Int = 0) -> UILabel {
    let label = UILabel()
    label.text = title
    label.font = UIFont.systemFont(ofSize: fontSize)
    label.textAlignment = alignment
    label.numberOfLines = numberOfLines
    return label
}

//let label = customLabel(title: <#T##String#>)

闭包的定义和调用

//: [Previous](@previous)

import Foundation

//闭包是一个匿名的函数快
//闭包被完成的包裹在大括号里面
//闭包的调用方式和函数一样
//闭包可以作为参数传递,也可以作为返回值

//闭包的定义和调用
//没有参数,没有返回值的闭包
let clousureOne = {
    print("hello,world")
}
clousureOne()

//有参数,没有返回值
//参数和执行语句都写在大括号里面,用 in 隔开
//闭包没有外部参数名
let clousureTwo = {
    (a: Int,b: Int) in
    print(a + b)
}
clousureTwo(5,10)

//有参数,有返回值
let clousureThree = {
    (a: Int,b: Int) -> Int in
    return a + b
}
let result = clousureThree(3,4)

闭包的使用

//需求:下载movie,更新UI
//1.下载,定义成函数
//2.更新,使用闭包
//使用最多的场景:异步加载数据,加载完成之后刷新UI
//异步加载数据:定义成函数
//加载完成数据之后刷新UI,定义成闭包
//把闭包作为参数传递
//在函数中执行闭包
import UIKit

class ViewController: UIViewController {

    func customLabel(title: String, fontSize: CGFloat = 13,alignment: NSTextAlignment = .left,numberOfLines: Int = 0,backgroundColor: UIColor = UIColor.yellow) -> UILabel {
        let label = UILabel(frame: CGRect(x: 20,y: 40,width: 300,height: 40))
        label.text = title
        label.font = UIFont.systemFont(ofSize: fontSize)
        label.textAlignment = alignment
        label.numberOfLines = numberOfLines
        label.backgroundColor = backgroundColor
        return label
    }
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        let label = customLabel(title: "正在下载...")
        view.addSubview(label)
        
//        func updateUI(movieName: String){
//            label.text = "\(movieName),下载完成"
//        }
        let updateUI = {
            (movieName: String) in
            label.text = "\(movieName),下载完成"
        }
        //下载电影,完成后更新UI
        downloadMovie(callBack: updateUI)
    }
    
    func downloadMovie(callBack:@escaping (String) -> ()) {
        //模拟异步加载数据
        DispatchQueue.global().async {
            Thread.sleep(forTimeInterval: 2)
            let movieName = "电影"
            DispatchQueue.main.async {
                //刷新UI
                callBack(movieName)
            }
        }
    }
}

尾随闭包

//尾随闭包:当闭包表达式作为函数的最后一个参数的时候,可以把闭包写在小括号外面,如果函数的参数,只有闭包一个参数,则连小括号都可以省略
//        DispatchQueue.global().async(execute: ??)
        DispatchQueue.global().async {
            Thread.sleep(forTimeInterval: 2)
            let movieName = "电影"
            DispatchQueue.main.async {
                //刷新UI
                callBack(movieName)
                
            }
        }
//下载电影,完成后更新UI
        //downloadMovie(callBack: updateUI)
        //尾随闭包的写法
        downloadMovie {
            (movieName: String) in
            label.text = "\(movieName),下载完成"
        }

guard的用法

//guard:保证
//guard:引导一个条件判断
//guard和if逻辑相同,写法相反
//if条件满足时,执行语句写在大括号里面,guard条件满足时,执行语句写在大括号外面,在大括号里面需要return,continue,break
//guard可以提前过滤条件不满足的情况,减少代码的层级

func testif() {
    var a = 10
    if a > 5 {
        print("hello")
    }
}
testif()

func testGuard() {
    var a = 10
    guard a > 5 else{
        return
    }
    print("hello,world")
}
testGuard()

func testUrl() {
    let url = URL(string: "http://www.baidu.com")
    if let url = url {
        let request = NSURLRequest(url: url)
    }
    
    guard let urls = url else {
        return
    }
    let request = NSURLRequest(url: urls)
}

闭包的循环引用

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

推荐阅读更多精彩内容

  • Swift 简介 查看Swift当前版本 简介 Swift 语言由苹果公司在 2014 年推出,用来撰写 OS X...
    mian小爬阅读 329评论 0 1
  • 简介 特点(1)优于OC,快速,安全(2)取消了预编译指令包括宏定义(OC用的太多了)(3)取消了OC指针和不安全...
    洛洛爱吃肉阅读 920评论 0 3
  • 还未更新完毕,后面会持续增加内容 常量&变量 什么是常量和变量 在Swift中规定:在定义一个标识符时必须明确说明...
    chenfanfang阅读 1,062评论 0 5
  • Swift 介绍 简介 Swift 语言由苹果公司在 2014 年推出,用来撰写 OS X 和 iOS 应用程序 ...
    大L君阅读 3,201评论 3 25
  • 1.基本定义 //1. swift中如何导入框架import UIKit //2.如何定义标识符 // swift...
    孤独的木木阅读 574评论 0 0