aliencode / aliencode.github.io

MIT License
0 stars 0 forks source link

swift基础.md #1

Open aliencode opened 9 years ago

aliencode commented 9 years ago

检查类型

用类型检查操作符(is)来检查一个实例是否属于特定子类型,返回 true 或 false 。

申明变量

var aaa = 1 //很长的数值可以用 _ 来分隔,如 111_222.1 = 111222.1

根据值判断变量类型

字符输出

println( "hello \(aaa) !" );

aaa 将被值替换.

字符串合并

var b = "aaa:" + String(a)

数组

var shoppingList = ["catfish", "water", "tulips", "blue paint"]

//key/value 形式

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

occupations["Jayne"] = "Public Relations"

申明空数组

let emptyArray = [String]() //赋值 emptyArray.append("1")
let anyArray = [Any]() //表示任意数据类型的数组
let emptyDictionary = [String: Float]()  //赋值 emptyDictionary["a"] = 1.0

用switch来判断读取anyArray数据

for thing in things {
    switch thing {
    case 0 as Int:
        println("zero as an Int")
    case 0 as Double:
        println("zero as a Double")
    case let someInt as Int:
        println("an integer value of \(someInt)")
    case let someDouble as Double where someDouble > 0:
        println("a positive double value of \(someDouble)")
    case is Double:
        println("some other double value that I don't want to print")
    case let someString as String:
        println("a string value of \"\(someString)\"")
    case let (x, y) as (Double, Double):
        println("an (x, y) point at \(x), \(y)")
    case let movie as Movie:
        println("a movie called '\(movie.name)', dir. \(movie.director)")
    default:
        println("something else")
    }
}

for-in使用

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

key/value形式遍历

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
        }
    }
}

if-else使用

var optionalString = "World" 

var optionalName: String? = "John Appleseed"  //申明变量为的值为可选的,不然 optionalName = nil 会报错
optionalName = nil

var greeting = "Hello!"

if let name = optionalName {  //如果 optionalName 不为 nil 则name将被赋值,不然跳过下面的代码块到else代码块。
    greeting = "Hello, \(name)"
}else
{
    greeting = "Hello, \(optionalString)"
}

switch使用

var vegetableComment=""

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

println(vegetableComment)

do,while使用

var n = 2

//条件在开始
while n < 100 { 
    n = n * 2
}

//条件在结尾
do {
    m = m * 2
} while m < 100

//范围
var firstForLoop = 0
for i in 0..<4 { //等同于:for var i = 0; i < 4; ++i 
    firstForLoop += i
}

0..<4 不包括4,如果要包括4,使用 0...4

函数和闭包


//函数申明

func greet函数名(name: String, day: String)函数参数 ->返回值 String {
    return "Hello \(name), today is \(day)."
}
greet("Bob", "Tuesday")

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

//返回一个元组
func calculateStatistics(scores: [Int]) -> (min2: Int, max2: Int, sum2: 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)
println(statistics.sum2) //使用返回元组的名称来取值
println(statistics.1) //索引来取值

//输出结果:
//(3, 100, 120)
//120
//100

//函数做为返回值,以及函数嵌套
func makeIncrementer() -> (String -> Int) {   //(String -> Int) 与返回函数的参数数据类型和返回值相同
    func addOne(number: String) -> Int {
         var a:Int? = number.toInt()
         if let b = a
         {
            return 1+b
         }
         else {return 1}
    }
    return addOne
}
var increment = makeIncrementer() //调用了makeIncrementer函数,返回addOne函数
println(increment("7"))  //return 8

//函数当做参数传入另一个函数
func hasAnyMatches(list: [Int], condition: Int -> Bool) -> Bool { //condition: Int -> 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)

//使用尾随闭包

hasAnyMatches(numbers){number -> Bool  in 
   return number < 10
}

//或者

hasAnyMatches(numbers){
   number < 10
}

闭包

let closure1  = {
    (number: Int) -> Int in  //用in将参数和返回值类型声明与闭包函数体进行分离
    let result = 3 * number
    return result
}
//等同于:
let closure1  = {number in 3 * number} //参数类型默认为Int型,通过 3* 来自动识别,返回计算结果
//等同于:
let closure1  = {3 * $0} //一切都是默认的,使用参数位置来访问参数

println(closure1(1))

对象和类

class NamedShape {
    var numberOfSides: Int = 0
    var name: String  //必须被初始化,或者定义为:var name: String?

    init(name: String) {  //构造方法
        self.name = name //初始化 name
    }
    deinit {
        println("deinitialized")
    }
    func simpleDescription() -> String {
        return "A shape with \(numberOfSides) sides."
    }
}

//继承
class EquilateralTriangle: NamedShape {
    var sideLength: Double = 0.0

    init(sideLength: Double, name: String) {
        self.sideLength = sideLength
        super.init(name: name) //父方法
        numberOfSides = 3 //父变量
    }

    var perimeter: Double {  //geter 和 seter 方法,不能和 willSet(set前) 和 didSet(set后) 共存
        set {
            sideLength = newValue / 3.0
        }
        get {
            return 3.0 * sideLength
        }
    }

    override func simpleDescription() -> String {  //覆盖父方法
        return "An equilateral triagle with sides of length \(sideLength)."
    }
}

class Triangle {
    var triangle: EquilateralTriangle { //申明 类 类型的变量
        willSet {
            println(newValue)
        }
    }
    var square:Double = 1{  //同时初始化
        willSet {
            triangle.sideLength = newValue
            println("willSet \(newValue)")
        }
        didSet(oldValue2) {
            println("didSet \(oldValue2)")
        }
    }
    init(size: Double, name: String) {
        println("init")
        triangle = EquilateralTriangle(sideLength: size, name: name)  //初始化变量
    }
}

var t = Triangle(size: 12, name: "assd")
t.square=21

didSet 实例

class Foo
{
    var propertyChangedListener : (Int, Int) -> Void = {  //一个返回为空,有两个参数的类方法
        println("The value of myProperty has changed from \($0) to \($1)")
    }

    var myProperty : Int = 0 {
        didSet { propertyChangedListener(oldValue, self.myProperty) }
    }
}
var f = Foo()
f.myProperty = 1

枚举

enum CompassPoint:Int {
  case North=1  //case 可以是一行或多行。给枚举项添加一个原始值如1,则其它的会自动叠加,如South值为2
  case South,East
  case West

  func simpleDescription() -> String { //扩展一个方法
        switch self {
        case .North:
            return "北"
        case .South:
            return "南"
        case .East:
            return "东"
        case .West:
            return "西"
        default:
            return String(self.rawValue)
        }
    }
}

var c = CompassPoint.North.rawValue //读取原始值
var c2 = CompassPoint.North //CompassPoint.init(rawValue:2) 通过原始值来取值

println(c)

c2 = .East //已知为CompassPoint类型,可以直接.East

switch c2 {
    case .East :
        println(c2.simpleDescription())
    case .North :
        println("c2")
    default:
        println("aa")
}

//相关值
//原始值是预先设置好的,可以通过rawValue读取。而相关值是可以在具体使用过程中指定。
enum Barcode {
  case UPCA(Int, Int, Int) 
  case QRCode(String)
}

var productBarcode = Barcode.UPCA(8, 85_909_51226, 3)
productBarcode = .QRCode("ABCDEFGHIJKLMNOP")

//读取相关值,注意let的用法。
switch productBarcode {
    case .UPCA(let numberSystem, let identifier, let check):
        println("UPC-A with value of \(numberSystem), \(identifier), \(check).")
    case let .QRCode(productCode):
        println("QR code with value of \(productCode).")
}

协议(接口)和扩展

协议

protocol ExampleProtocol {
    var simpleDescription: String { get }
    mutating func adjust() //如果是枚举或结构实现此协议,在方法前加mutating,协议方法前面必须加mutating关键字。
}

class SimpleClass: ExampleProtocol {
    var simpleDescription: String = "A very simple class."
    var anotherProperty: Int = 69105
    func adjust() {  //类方法前不需要加mutating
        simpleDescription += "  Now 100% adjusted."
    }
}
var a = SimpleClass()
a.adjust()

扩展

extension Int: ExampleProtocol {  //对原生的类方法扩展额外的功能
    var simpleDescription: String { //给Int型数据添加方法simpleDescription
        return "The number \(self)"
    }
    mutating func adjust() { //使用mutating关键词声明了一个方法adjust改动了Int结构
        self += 42
    }
}

或者:
extension Int { 
    var simpleDescription: String { 
        return "The number \(self)"
    }
}

println(7.simpleDescription)

泛型

func repeat<ItemType先预设一个未知数据类型供在参数或函数体里使用>(item: ItemType, times: Int) -> [ItemType] {  //ItemType 将被自动识别为String
    var result = [ItemType]() 
    for i in 0..<times {
        result.append(item)
    }
    return result
}
repeat("knock", 4)

类和结构

类和结构基本相同,最大的区别是类是引用类型,结构是值类型

闭包和函数也是 引用类型

引用类型就是变量和它赋值的类、函数或闭包指向同一内存位置。参考 http://numbbbbb.gitbooks.io/-the-swift-programming-language-/content/chapter2/07_Closures.html#closures_are_reference_types

//定义一个结构,里面的变量自动生成构造
struct task{
    var name = "name"
    var desc = "desc"
}
var t1 = task(name:"1", desc:"222") //结构里面的变量自动生成构造
var t2 = t1
t2.name = "name xxx" //不影响t1的值
println(t1.name)

class a{
    var a = 1
    var b = 2
}
var a1 = a()
var a2 = a1
a2.a=3 //会影响a1的值
println(a1.a)
aliencode commented 9 years ago

关于 ? 和 !的用法 http://letsswift.com/2014/06/swift-questionmark-exclamatorymark/

? 说这个变量是个值不确定的,,有可能为 nil

通过可选绑定来取值,如

var strValue:String?

if let str = strValue {
    let hashValue = str.hashValue
}

或者通过 strValue!

! 说这个变量我确定它有值,,你给你取出来

! 除了取可选值以外还可以暗示此变量一定有值

aliencode commented 9 years ago

函数调用参数名省略规则

  1. 构造函数 需要指定所有参数名称
  2. 全局函数 省略所有参数名称
  3. 内部函数 省略第一个参数名称
aliencode commented 9 years ago

静态方法和类

  1. 枚举和结构体 关键字是static
  2. 类 关键字是class。
aliencode commented 9 years ago

输入输出参数(In-Out Parameters)

接收变量地址

func swapTwoInts(inout a: Int, inout b: Int) {
    let temporaryA = a
    a = b
    b = temporaryA
}

//调用
var someInt = 3
var anotherInt = 107
swapTwoInts(&someInt, &anotherInt)
println("someInt is now \(someInt), and anotherInt is now \(anotherInt)")
// prints "someInt is now 107, and anotherInt is now 3”
aliencode commented 9 years ago

元组

  1. 申明:
let http404Error = (404, "Not Found")
//指定个名称
let http200Status = (statusCode: 200, description: "OK")

//访问 http404Error.0 或者 http200Status.statusCode
  1. 分解:
//将一个元组的内容分解成单独的常量和变量
let (statusCode, statusMessage) = http404Error
//忽略某个值
let (justTheStatusCode, _) = http404Error
aliencode commented 9 years ago

didSetwillSet 不会在类的 init 方法中触发