Swift学习笔记一

  最近计划把Swift语言系统学习一下,然后将MagViewer用这种新语言重构一次,并且优化一下,这里记录一下Swift的学习笔记。

  Swift和Objective-C相比,在语法和书写形式上做了很多改进,面向开发者的体验更好了。比如:

  println("Hello, world!")

  就可以打印出这个字符串,这条语句就是完整的一句,句末不需要添加分号,也不需要引入额外的头或者库文件比如标准输入输出等。在全局作用域内书写的代码就会作为程序的入口,因此不需要编写main函数了。

  简单值

  用let声明常量,用var声明变量。常量的值在编译的时候不需要知道,但是必须在某个地方真正给它赋值一次,因此常量通常是在一个地方声明和赋值,在很多地方使用的。

var myVariable = 42
myVariable = 50
let myConstant = 42

  常量和变量的类型必须和所赋的值保持一致。但是,并不用每次都显示地写明变量类型,可以只给它们提供值,而让编译器去推测它们的类型。上面的例子就是这样的,也可以显示地写明类型:

let explicitDouble: Double = 70

  变量不会隐式地进行类型转换,如果需要类型转换,必须要开发者显示地进行,比如:

let label = "The width is "
let width = 94
let widthLabel = label + String(width)

  在字符串中引用变量还有更简单的方式,就是直接用反斜杠加上圆括号就可以了,比如:

let apples = 3
let oranges = 5
let appleSummary = "I have \(apples) apples."
let fruitSummary = "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"

创建空数组或空字典时,用初始化语法更为简便:

let emptyArray = [String]()
let emptyDictionary = [String: Float]()

如果元素类型能够被推理出来,甚至可以省略类型声明,用[]表示空数组,[:]表示空字典,比如:

shoppingList = []
occupations = [:]

控制流

  用if和switch做条件选择,用for-in,for,while,do-while做循环,选择条件的圆括号和循环变量是可以省略的,但是主体部分的大括号不能省略:

let individualScores = [75, 43, 103, 87, 12]
var teamScore = 0
for score in individualScores {
    if score > 50 {
        teamScore += 3
    } else {
        teamScore += 1
    }
}
println(teamScore)

在if结构中,条件语句的值必须是一个Boolean表达式,这就使得上面的例子中if score {。。。}无法通过,而不是将score值隐式地转换了。

if和let可以结合使用,这样可以避免找不到该变量。这种变量相当于可省略的,可省略的变量要么等于某个值,要么就是nil(未找到该变量),在变量类型之后加上一个?来标明该变量是可省略的:

var optionalString: String? = "Hello"
println(optionalString == nil)

var optionalName: String? = "John Appleseed"
var greeting = "Hello!"
if let name = optionalName {
    greeting = "Hello, \(name)"
}

switch支持任何数据类型以及很多种条件比较表达式(并不限定为整数或者判断是否相等):

let vegetable = "red pepper"
switch vegetable {
case "celery":
    let vegetableComment = "Add some raisins and make ants on a log."
case "cucumber", "watercress":
    let vegetableComment = "That would make a good tea sandwich."
case let x where x.hasSuffix("pepper"):
    let vegetableComment = "Is it a spicy \(x)?"
default:
    let vegetableComment = "Everything tastes good in soup."
}//Is it a spicy red pepper?

default分支是必须的,否则编译会报错。

注意是如何用let将满足一个表达式的值赋给一个常量的。

在进入合适的case之后,程序会跳出switch块,忽略其他case,因此不需要在每个case最后都加上break;

用for in来遍历数组或字典,数组是按顺序排列的,而字典则是随机排列的键值对。

let interestingNumbers = [
    "Prime": [2, 3, 5, 7, 11, 13],
    "Fibonacci": [1, 1, 2, 3, 5, 8],
    "Square": [1, 4, 9, 16, 25],
]
var largest = 0
for (kind, numbers) in interestingNumbers {
    for number in numbers {
        if number > largest {
            largest = number
        }
    }
}
println(largest)

white和do-while用来做循环:

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

var m = 2
do {
    m = m * 2
} while m < 100
println(m)

当然,在循环体中可以引用当前的index,要么用..<来创建index的范围,或者显示地声明初始值,条件语句和递增量,这两种方法是完全等价的:

var firstForLoop = 0
for i in 0..<4 {
    firstForLoop += i
}
println(firstForLoop)

var secondForLoop = 0
for var i = 0; i < 4; ++i {
    secondForLoop += i
}
println(secondForLoop)

..<不包含范围的最大值,而...包含范围的最大值和最小值

函数和闭包

用func来声明函数,用->来标明函数的返回值:

func greet(name: String, day: String) -> String {
    return "Hello \(name), today is \(day)."
}
greet("Bob", "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([5, 3, 100, 3, 9])
println(statistics.sum)
println(statistics.2)

函数也可以接受不定个数的变量,把它们全部包含进一个数组,比如:

func sumOf(numbers: Int...) -> Int {
    var sum = 0
    for number in numbers {
        sum += number
    }
    return sum
}
sumOf()
sumOf(42, 597, 12)

函数是可以嵌套的,内部函数可以访问外部函数的变量(JS中的闭包)

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)
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(numbers, lessThanTen)

函数其实是闭包的一种特殊情况而已:就是可以在程序的其他地方被调用的代码块。闭包里的代码可以访问闭包被创建时所在的作用域链上的变量或者函数,不管闭包在执行的时候是在哪个作用域,嵌套函数就很好地说明这个问题了。

编写匿名闭包可以通过将代码包含在大括号里边,用in将参数序列及返回值和函数体分开:

numbers.map({
    (number: Int) -> Int in
    let result = 3 * number
    return result
})

闭包可以写得更简洁,如果闭包的类型是已知的,比如某个代理的回调,则可以省略它的参数类型和返回值类型。

let mappedNumbers = numbers.map({ number in 3 * number })
println(mappedNumbers)

变量的引用也可以用数字而非名字,这在短闭包中非常有用。被作为最后一个参数传递给函数的闭包可以直接在圆括号之后出现:

let sortedNumbers = sorted(numbers) { $0 > $1 }
println(sortedNumbers)

这一篇就到这里吧,接下来就要接触到类相关的语法了。

时间: 2024-11-05 02:31:03

Swift学习笔记一的相关文章

SWIFT学习笔记05

1.Swift 无需写break,所以不会发生这种贯穿(fallthrough)的情况.2.//用不到变量名,可用"_"替换 for _ in 1...power { answer *= base } 3.case 可以匹配更多的类型模式,包括区间匹配(range matching),元组(tuple)和特定类型的描述. 可以这样用case case 1...3: naturalCount = "a few" 4.如果存在多个匹配,那么只会执行第一个被匹配到的 ca

SWIFT学习笔记02

1.//下面的这些浮点字面量都等于十进制的12.1875: let decimalDouble = 12.1875 let exponentDouble = 1.21875e1 let hexadecimalDouble = 0xC.3p0//==12+3*(1/16) 2.//类型别名,用typealias关键字来定义类型别名 typealias AudioSample = UInt16 var maxAmplitudeFound = AudioSample.min 3.//元组 let ht

swift学习笔记(三)关于拷贝和引用

在swift提供的基本数据类型中,包括Int ,Float,Double,String,Enumeration,Structure,Dictionary都属于值拷贝类型. 闭包和函数同属引用类型 捕获则为拷贝.捕获即定义这些常量和变量的原作用域已不存在,闭包仍然可以在闭包函数体内引用和修改这些值 class属于引用类型. Array的情况稍微复杂一些,下面主要对集合类型进行分析: 一.关于Dictionary:无论何时将一个字典实例赋给一个常量,或者传递给一个函数方法时,在赋值或调用发生时,都会

Swift学习笔记十二:下标脚本(subscript)

下标脚本就是对一个东西通过索引,快速取值的一种语法,例如数组的a[0].这就是一个下标脚本.通过索引0来快速取值.在Swift中,我们可以对类(Class).结构体(structure)和枚举(enumeration)中自己定义下标脚本的语法 一.常规定义 class Student{ var scores:Int[] = Array(count:5,repeatedValue:0) subscript(index:Int) -> Int{ get{ return scores[index];

Swift学习笔记四:数组和字典

最近一个月都在专心做unity3d的斗地主游戏,从早到晚,最后总算是搞出来了,其中的心酸只有自己知道.最近才有功夫闲下来,还是学习学习之前的老本行--asp.net,现在用.net做项目流行MVC,而不是之前的三层,既然技术在更新,只能不断学习,以适应新的技术潮流! 创建MVC工程 1.打开Visual studio2012,新建MVC4工程 2.选择工程属性,创建MVC工程 3.生成工程的目录 App_Start:启动文件的配置信息,包括很重要的RouteConfig路由注册信息 Conten

Swift学习笔记(二)参数类型

关于参数类型,在以前的编程过程中,很多时间都忽视了形参与实参的区别.通过这两天的学习,算是捡回了漏掉的知识. 在swift中,参数有形参和实参之分,形参即只能在函数内部调用的参数,默认是不能修改的,如果想要修改就需要在参数前添加var声明. 但这样的声明过后,仍旧不会改变实参的值,这样就要用到inout了,传递给inout的参数类型必须是var类型的,不能是let类型或者字面类型,(字面类型是在swift中常提的一个术语,个人认为就是赋值语句,也不能修改)而且在传递过程中,要用传值符号"&

Swift学习笔记十:属性

1.存储属性       1. 作为特定类或结构实例的一部分,存储属性存储着常量或者变量的值.存储属性可分为变量存储属性(关键字var描述)和常量存储属性(关键字let描述). struct student{ let name = "" var score = 0 } let a = student(name:"小笨狼",score:96)           注意:                ① 定义储存属性时,需要为每一个属性定义一个默认值.在初始化的时候,

Swift学习笔记(4)--字符串及基本使用

String是例如"hello, world","海贼王" 这样的有序的Character(字符)类型的值的集合,通过String类型来表示. Swift 的String类型与 Foundation NSString类进行了无缝桥接.如果您利用 Cocoa 或 Cocoa Touch 中的 Foundation 框架进行工作.所有NSString API 都可以调用您创建的任意String类型的值.除此之外,还可以使用本章介绍的String特性.您也可以在任意要求传

Swift学习笔记

Apple 新推的Swift已经好几天了.对于向我这样的oc都还没完全琢磨透彻的菜鸟来说--(简直就是福利啊,joke) 看了几天的Swift,只是有了基本的印象.总感觉比较换混乱,可能源自与自己没怎么学过脚本语言.索性,边看边记,加深印象. 本来部分内容源自Apple的<The Swift Programming Language>以及互联网教程.其余内容均为个人理解,不保证正确. 进入正题: 1.Swift是什么? Apple唤他作:雨燕.其实英语过了四级的都应该看出来,Swift还有一层

Swift学习笔记(一):No such module &#39;Cocoa&#39;

在xcode中创建一个Playground文件, 进行导包操作 ,import Cocoa 却提示No such module 'Cocoa' 原因是该Playground文件的platform 设置成了iOS,改为OS X 即可 如果进行导包操作 ,import UIKit 却提示No such module 'UIKit' 则原因相反,改为iOS即可 打开File Inspector,如下图设置 Swift学习笔记(一):No such module 'Cocoa'