Swift 入门基础

1、常量和变量

  • 变量: var 常量: let
    • 常量&变量的使用原则:尽量先用 let,只有需要变的时候,再用 var,能够更加安全
var 定义变量,设置之后可以修改
let 定义常量,设置之后不可以修改
语句末尾不用使用 `;`
在 Swift 中使用 `print()` 替代 OC 中的 `NSLog`
`print` 的性能更好

// 定义变量
var i = 10
print(i)
i = 15
print(i)

let j = 20
// 常量一经定义不能自改数值
//        j = 25
print(j)
  • 定义 OC 对象
// 实例化视图
let v = UIView(frame: CGRectMake(0, 0, 100, 100))
// 设置背景颜色, 当前对象的属性,不需要使用 `self.`
v.backgroundColor = UIColor.redColor() 

// 添加到根视图
view.addSubview(v) 

使用 `let` 修饰 `v` 并且赋值,
表示 `该常量的内存地址不允许修改,但是可以修改其内部的属性`
  • 类型推导
    • 使用自动类型推导好处: 大大降低代码中的冗余代码
  - Swift中如果在定义变量/常量时进行初始化, 那么数据类型可以不用写, 系统会自动根据右边的复制推导出变量/常量的类型
  - Swift开发中能不写数据类型就不写数据类型, 尽量使用编译器的自动推导
  - 只有当我们需要明确的指定数据的长度, 获取需要先定义再初始化时才明确的指定数据类型

 let number3 = 10.10

 var number4: Int  
 number4 = 99
  • 类型转换
    • Swift中只有显示转换没有隐式转换,
OC中有显示转换和隐式转换 double value = 10.1 + 9
Swift中只有显示转换没有隐式转换, 也就是说只有相同类型的数据才能进行赋值和计算
// 只有相同数据类型才能赋值
let number5: Int = Int(55.5)

// 只有相同数据类型才能进行运算
let number6 = 10
let number7 = 88.8
let sum = Double(number6) + number7

// CGFloat --> double

let size = CGSize(width: 10, height: 10)
let number8 = 10.1
let sum2 = size.width + CGFloat(number8)

2、元祖

元祖.png

3、逻辑分支

  • for
import UIKit

/*
普通for循环, 和OC中基本一致
*/
// 0~9
for var i = 0;i < 10;i++
{
    print(i)
}

// Swift特色循环
// 0..<10 代表一个区间范围 从0开始到9, 包含头不包含尾
// Swift1.0时 0..10
for i in 0..<10
{
    print(i)
}

// _ 代表忽略, 如果不关心某个参数, 就可以使用_
// 在Swift开发中 _ 使用频率非常高
for _ in 0..<10
{
    print("lnj")
}

// 0...10 代表一个区间范围 从0开始到10, 包含头又包含尾
for i in 0...10
{
    print(i)
}
  • while
/*
Swift中的while循环和OC中差不多, 而且在开发中很少使用while
*/

var a = 0
while a < 10
{
    print(a)
    a++
}

/*
Swift升级到2.0之后, do while循环发生了很大的变化
do while没有do了, 因为do被用作捕获异常了
*/

var b = 0
repeat{
    print(b)
    b++
}while b<10
  • if
var i = 10

if i > 0 {
    print("OK")
}
* 阶段性小结
    * `Swift` 中没有 C 语言中的`非零即真`概念
    * 在逻辑判断时必须显示地指明具体的判断条件
    * `if` 语句条件的 `()` 可以省略
    * 但是 `{}` 不能省略
  • switch
Swift中的switch
1. 后面的()可以省略
2.OC中的switch如果没有break会穿透, 但是OC中不会, Swift不会穿透
3.OC中如果要在case中间定义变量, 必须加上{}确定作用域, 而Swift中不用
4.OC中default的位置可以随便写, 只有所有case都不满足才会执行default
而Swift中的default只能放在最后
5.OC中的default可以省略, Swift中"大部分"情况下不能省略

switch num{
    case 1:
        print("1")
        let value = 998
    case 5:
        print("5")
    case 10:
        print("10")
    default:
        print("other")
}
  • Bool类型
C语言和OC并没有真正的Bool类型,非0即真
OC语言的Bool类型YES/NO是`typedef signed char BOOL;`

Swift引入了真正的Bool类型
Swift中没有C和OC中非零即真的概念
Swfit中逻辑值只有两个true/false
  • 三目
var a = 10
var b = 50

var result = a > b ? a : b
print(result)
* 阶段性小结
    * `Swift` 中的 `三目` 运算保持了和 OC 一致的风格
  • guard
    • guard一般用于避免使用强制拆包, 优化代码结构
guard语句是在Swift 2.0中引进的,它是用途是在未满足某个条件时,提供一个退出的路径
guard语句判断其后的表达式布尔值为false时,才会执行之后代码块里的代码,如果为true,则跳过整个guard语句

4、可选类型 / 可选绑定

  • 可选类型
可选类型
* 什么是可选类型: 一个变量可以有值也可以没有值, 我们就称之为可选类型
* 在Swift中如果使用一个可选类型的变量/常量, 必须解包操作
* 解包: 只需要在变量/常量后面加上 !
* !含义: 代表告诉系统该变量/常量中一定有值, 如果强制解包一个没有值的常量/变量,那么会报错

* 优点: 提高代码阅读性
* 格式: 修饰符 变量名称:Optional<数据类型>
        修饰符 变量名称: 数据类型?
* 语法糖: 因为在Swift中可选类型用得非常非常多, 所以为了简化代码, Swift提供了一个语法糖, 可以用? 代替 Optional<数据类型>

提示:
对于初学者来说 ? ! 是最为头疼的语法, 刚开始的时候建议利用Xocde的语法提示来解决? !的问题
*/
//var number: Optional<Int> = nil
//var number2: Int = nil

let number: Optional<Int> = 10
print(number!)
let number2 = 10
let sum = number! + number2


let number3: Int? = 55
print(number3)

/*
可选类型注意点:
* 在开发中一般情况下尽量不要强制解包一个可选类型, 否则会引发错误
*/

//let url = NSURL(string: "http://baidu.com")
//print(url)
//let request = NSURLRequest(URL: url!)

let url = NSURL(string: "http://baidu.com")
print(url)
//let request = NSURLRequest(URL: url!)
if url != nil
{
    let request = NSURLRequest(URL: url!)
}
  • 可选绑定
// 可选绑定: 如果url不为nil, 系统内部就会自动将解包之后的值赋值给temp, 并且只有temp有值时才会执行{}中的代码
// Swift开发中推荐这种写法
if let temp = url
{
    let request = NSURLRequest(URL: temp)
}

5、数组

  • OC
可变于不可变NSArray/NSMutableArray
空数组:
   NSArray *arr1 = [NSArray array];
   NSArray *arr2 = @[];
有值数组:
   NSArray *arr1 = [NSArray arrayWithObjects:@1, @2, @3, nil];
   NSArray *arr2 = @[@1, @2, @3];
  • swift
    • 数组中保存的对象类型
// 数组中保存的都是字符串
let arr = ["zhangsan", "lisi"]

// 数组中保存的是 NSObject
let arr1 = ["zhangsan", 1]
* 阶段性小结
* 数组使用 [] 定义,这一点与 OC 相同
* 如果初始化时,所有内容类型一致,择数组中保存的是该类型的内容
* 如果初始化时,所有内容类型不一致,择数组中保存的是 `NSObject`
  可变于不可变let/var

  空数组:
    var arr1 = Array<Int>()
    var arr2 = [Int]()
    var arr3 = []
  有值数组:
    var arr1: Array<Int> = [1, 2, 3]
    var arr2: Array = [1, 2, 3]
    var arr3: [Int] = [1, 2, 3]
    var arr4 = [1, 2, 3]

* 阶段性小结
    * 如果定义数组时指定了保存对象的类型,择不能向数组中添加其他类型的内容
    * 可以使用 `[String]()`
    * `let` 定义的数组是`不可变的`
    * `var` 定义的数组是`可变的`
  • 常见数组操作
// 定义只能保存字符串类型数组
var array: [String]

// 初始化数组
array = ["zhangsan"]

// 添加元素
array.append("lisi")

print(array)

// 删除元素
array.removeAtIndex(1)
print(array)

// 删除所有元素
array.removeAll(keepCapacity: true)
print(array.capacity)

// 注意数组容量的变化
for i in 0..<10 {
    array.append("\(i)")
    print("\(array) --- \(array.capacity)")
}

// 实例化新的数组
var array2 = [String]()
array2.append("1")
array2.append("2")

// 拼接数组
array += array2

print(array)

 // 更新
 arrayM[0...1] = ["a", "b"]

 // 删除
 //arrayM3.removeRange(Range(start: 0, end: 2))
 arrayM3.removeRange(0..<2) // 其实Range就是半闭区间
  • 在Swift语言里,我们可以用快速枚举(for-in
    )的方式来遍历整个数组的元素:
for (index, value) in enumerate(array) { 
 println("Item \(index + 1): \(value)")
}

下面是使用 for-in 遍历数组里的元素:
let numberOfLegs = ["spider": 8, "ant": 6, "cat": 4]
for (animalName, legCount) in numberOfLegs { 
  println("\(animalName)s have \(legCount) legs")
}
//spiders have 8 legs
//ants have 6 legs
//cats have 4 legs
由于字典是无序的,因此迭代的顺序不一定和插入顺序相同。

6、字典

/// 定义并实例化字典
var dict = [String: AnyObject]()

dict["name"] = "zhangsan"
dict["age"] = 18

print(dict)

// 设置相同 key,之前的数值会被覆盖
dict["name"] = "lisi"
print(dict)

// 删除某一个 key
dict.removeValueForKey("age")
print(dict)

dict["title"] = "manager"
print(dict)

// 遍历字典(k, v可以随便写)
for (k, v) in dict {
    print("\(k) -- \(v)")
}

// 合并字典
var dict2 = ["name": "wangwu", "age": 80, "title": "boss"]
for (k, v) in dict2 {
    dict.updateValue(v, forKey: k)
}
print(dict)

7、 字符串

  • 在 Swift 中绝大多数的情况下,推荐使用 String 类型

  • 使用 String 的原因

     * `String` 是一个结构体,性能更高
       * `String` 目前具有了绝大多数 NSString 的功能
       * `String` 支持直接遍历
     * `NSString` 是一个 `OC` 对象,性能略差
     * `Swift` 提供了 `String` 和 `NSString` 之间的无缝转换
    
  • 遍历字符串
let str = "我要飞的更High"

for s in str {
   print(s)
}
  • 字符串拼接
let str1 = "zhangsan"
let str2 = "lisi"
let i = 10

print(str1 + str2)
print("\(str1) \(str2) \(i)")
  • 阶段性小结
    • 直接在 "" 中使用 \(变量名) 的方式可以快速拼接字符串
    • 小伙伴们再也不要考虑 stringWithFormat
  • 格式化字符串
for _ in 0...10 {
    let str = String(format: "zhangsan - %04d", arguments: [arc4random_uniform(100)])
    print(str)
}
* 阶段性小结
    * 在实际开发中,如果需要指定字符串格式,可以使用 `String(format:...)` 的方式
    * 注意:后面的参数需要放在一个数组中
  • String & Range 的结合
  • 以下是超级费劲的代码
let str: String = "我要飞的更High"

var subStr = str.substringWithRange(Range<String.Index>(start: str.startIndex, end: str.endIndex))
print(subStr)
  • 建议写法
let str1: NSString = "我要飞的更High"
print(str1.substringWithRange(NSMakeRange(0, 3)))

8、函数

* swift 函数定义格式:
  func 函数名称(形参列表) ->返回值类型
  {
    代码
  }
* Void == ()

// 1.没有参数没有返回值
func say() -> Void
{
    print("hi")
}
say()
// 如果没有返回值可以简写
func say1() -> ()
{
    print("hi")
}
say1()

func say2()
{
    print("hi")
}
say2()


// 2.有参数没有返回值
// Swift2.0开始, 会自动将形参列表的第二个参数名称作为标签
// Swift2.0之前是没有这个特性的, 在Swift2.0之前如果需要显示标签需要在形参名称前面加上#
func sum(num1: Int, num2: Int)
{
    print(num1 + num2)
}
sum(10, num2: 20)


// 添加标签, 添加外部参数
// x/y称之为外部参数, a/b称之为内部参数
func sum2(x a: Int,y b: Int)
{
    print(a + b)
}
sum2(x: 10, y: 20)

// Swift2.0之前的写法, 只要加上#那么a/b既是外部参数, 也是内部参数
//func sum2(#a: Int,#b: Int)
//{
//    print(a + b)
//}
//sum2(a: 10, b: 20)

// 3.没有参数有返回值
func getNumber() -> Int
{
    return 998
}
print(getNumber())

// 4.有参数有返回值
func sum2(num1: Int, num2: Int) -> Int
{
    return num1 + num2
}
print(sum2(50, num2: 50))


// 内部和外部参数
/*
* 默认情况下所有形参都是内部参数, 也就是说只能在函数内部使用
* 从Swift2.0开始会自动将形参列表的第二个参数名称作为标签, 也就是说从第二个参数开始, 参数的名称既是内部参数又是外部参数
* 如何指定外部参数?
*/
func sum3(num1: Int, y num2: Int)
{
    print("num1 = \(num1), num2 = \(num2)")
    print(num1 + num2)
}
//sum3(10, num2: 20)
sum3(10, y: 20)

// 默认参数
// 如果指定了默认值, 那么在调用方法的时候就可以不用传递数据, 如果不传递数据系统就会使用默认值, 如果传递了就会使用传递的值
// 在其它语言里面, 默认值一般情况只能是最后一个参数, 但是Swift可以写在任何位置
func joinString(str1: String, str2: String = "在", str3: String) -> String
{
    return str1 + str2 + str3
}
joinString("a", str2: "也在", str3: "1")
joinString("b", str3: "1")


// 常量参数和变量参数以及inout参数
// 默认情况下所有形参都是常量参数, 不能在函数中修改形参的值
// 如果想在函数中修改形参的值, 那么必须把形参变为变量参数
// 和OC一样, 在函数中修改形参的值不会影响到外面实参的值
// 如果想在函数中修改形参之后影响实参, 那么必须把形参变为inout参数

//func swap(a: Int, b: Int)
//{
//    let temp = a
//    a = b  // 不能修改常量参数
//    b = temp
//}

//func swap(var a: Int, var b: Int)
//{
//    print("a = \(a), b = \(b)")
//    let temp = a
//    a = b
//    b = temp
//    print("a = \(a), b = \(b)")
//}

func swap(inout a: Int, inout b: Int)
{
    print("a = \(a), b = \(b)")
    let temp = a
    a = b
    b = temp
    print("a = \(a), b = \(b)")
}

var x = 10
var y = 20
print("x = \(x), y = \(y)")
swap(&x, b: &y)
print("x = \(x), y = \(y)")

// 可变参数
// 只要参数是可变参数, 就可以传递一个或多个值
// 在其它语言中一般情况下可变参数只能是最后一个形参, 而Swift中可以写在任意位置, 但是为了提高代码的阅读性, 还是建议写在最后
func sum4(nums: Int..., temp: Int) -> Int
{
    var sum = 0
    for i in nums
    {
        sum += i
    }
    return sum + temp
}
sum4(1, 2, 3, temp: 10)

// 函数嵌套
// 将一个函数写到另外一个函数的函数体中, 外面称之为函数嵌套
// 1.被嵌套的函数只能在父函数内部访问
// 2.被嵌套的函数可以访问外部的变量
// 应用场景: 两个函数之间依赖较强, 或者一个函数就只给另外一个函数使用
//          例如: 对数组排序是一个函数, 交换变量又是一个函数, 他们就可以使用函数嵌套
let value = 55
func test()
{
    let number = 10
    func demo()
    {
        print("----\(number), \(value)")
    }
    demo()
}
test()
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 196,264评论 5 462
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 82,549评论 2 373
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 143,389评论 0 325
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,616评论 1 267
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,461评论 5 358
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,351评论 1 273
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,776评论 3 387
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,414评论 0 255
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,722评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,760评论 2 314
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,537评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,381评论 3 315
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,787评论 3 300
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,030评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,304评论 1 252
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,734评论 2 342
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,943评论 2 336

推荐阅读更多精彩内容