Swift中文教程(1)-简介

转载请注明 http://write.blog.csdn.net/postedit/28442151

翻译者:gumpstar

昨天Swift刚出来,以后自己可能会在手机上开发计算机视觉应用,就打算每天学习一点点。

简介

Swift是供iOS和OS X应用编程的新编程语言,基于C和Objective-C,而却没有C的一些兼容约束。Swift采用了安全的编程模式和添加现代的功能来是的编程更加简单、灵活和有趣。界面则基于广受人民群众爱戴的Cocoa和Cocoa Touch框架,展示了软件开发的新方向。

  Swift在市场存在了多年。Apple基于已有的编译器、调试器、框架作为其基础架构。通过ARC(Automatic Reference Counting,自动引用计数)来简化内存管理。我们的框架栈则一直基于Cocoa。Objective-C进化支持了块、collection literal和模块,允许现代语言的框架无混乱即可使用。感谢这些基础工作,才使得可以在Apple软件开发中引入新的编程语言。

  Objective-C开发者会感到Swift的似曾相识。Swift采用了Objective-C的命名参数和动态对象模型。提供了对Cocoa框架和mix-and-match的互操作性。基于这些基础,Swift引入了很多新功能和结合面向过程和面向对象的功能。

 

  Swift对新的程序员也是友好的。他是工业级品质的系统编程语言,却又像脚本语言一样的友好。他支持playground,允许程序员实验一段Swift代码功能并立即看到结果,而无需麻烦的构建和运行一个应用。

  Swift集成了现代编程语言思想,以及Apple工程文化的智慧。编译器是按照性能优化的,而语言是为开发优化的,无需互相折中。可以从"Hello, world"开始学起并过渡到整个系统。所有这些使得Swift成为Apple软件开发者创新的源泉。

  Swift是编写iOS和OSX应用的梦幻方式,并且会持续推进新功能的引入。我们对 Swift充满野心,我们迫不及待的看到你用他来做点什么。

第一个程序

我们来看看hello world

println("Hello, world")

对,这就是全部代码,只有一行!!!不需要包含库,比如<iostream>,也不需要分号,也不需要main函数,因为在全部范围(global scope)写的代码就是程序的进入点(entry point)

简单值

let语句创建一个常量,var创建一个变量,常量值不需要在编译时(compile
time)就知道,但是必须只能赋值一次

var myVariable = 42
myVariable = 50
let myConstant = 42

如果要进行赋值,类型要一致.但是你不需要显示写出类型,编译器会自动推导,在上面的例子中,编译器就推导出了myVariable是一个整型.

当然可以显示指定,如下使用了一个冒号显示声明为Double类型

let implicitInteger = 70
let implicitDouble = 70.0
let explicitDouble: Double = 70

EXPERIMENT

Create a constant with an explicit type of Float and a value of 4.

let explictFloat: Float = 4

值不会隐式转化为另一种类型,必须要显示转化

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.

PHP中也有这样的格式

使用[]创建数组和字典,在方括号里用下标(index)或者键值(key)来访问元素

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 = Dictionary<String, Float>()

如果类型可以被推导,那么就可以使用[]来初始化数组或者[:]来初始化字典,比如说,当你要将它们作为参数传递给一个函数,就不需要显示指定类型了。

shoppingList = []   // Went shopping and bought everything.

控制流

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

一个if语句必须是bool类型的

这意味着if score{...}这种语句是错误的

有optional类型,跟SML有些类似.

一个optional value要么包含一个值,要么是nil,在类型后面插入?表示这是一个optional

var optionalString: String? = "Hello"
optionalString == nil

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

假如optionalName是nil,那么if语句就是false,

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

不用写break语句,进入那个case后会退出

使用for-in来迭代字典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
        }
    }
}
largest

while语句基本无变化

var n = 2
while n < 100 {
    n = n * 2
}
n

var m = 2
do {
    m = m * 2
} while m < 100
m

可以使用..来表示一个range,如下,两段代码做的事情是一样的

0..3表示[0,3),0...3表示[0,3]

var firstForLoop = 0
for i in 0..3 {
    firstForLoop += i
}
firstForLoop

var secondForLoop = 0
for var i = 0; i < 3; ++i {
    secondForLoop += 1
}
secondForLoop

其实感觉swift的函数就是函数式编程语言的东西

使用func关键字声明函数,使用->声明函数返回类型

[cpp] view
plain
copy

  1. func greet(name: String, day: String) -> String {
  2. return "Hello \(name), today is \(day)."
  3. }
  4. greet("Bob", "Tuesday")

也可以返回元组

[cpp] view
plain
copy

  1. func getGasPrices() -> (Double, Double, Double) {
  2. return (3.59, 3.69, 3.79)
  3. }
  4. getGasPrices()

也可以接收变参

[cpp] view
plain
copy

  1. func sumOf(numbers: Int...) -> Int {
  2. var sum = 0
  3. for number in numbers {
  4. sum += number
  5. }
  6. return sum
  7. }
  8. sumOf()
  9. sumOf(42, 597, 12)

函数可以嵌套

[cpp] view
plain
copy

  1. func returnFifteen() -> Int {
  2. var y = 10
  3. func add() {
  4. y += 5
  5. }
  6. add()
  7. return y
  8. }
  9. returnFifteen()

函数是第一等公民(函数式编程嘛......),函数可以返回函数,也可以接收函数

下面这个函数返回一个函数(接收一个int返回一个int的函数),

[cpp] view
plain
copy

  1. func makeIncrementer() -> (Int -> Int) {
  2. func addOne(number: Int) -> Int {
  3. return 1 + number
  4. }
  5. return addOne
  6. }
  7. var increment = makeIncrementer()
  8. increment(7)

下面这个函数接收一个函数(接收一个int返回bool的函数)

[cpp] view
plain
copy

  1. func hasAnyMatches(list: Int[], condition: Int -> Bool) -> Bool {
  2. for item in list {
  3. if condition(item) {
  4. return true
  5. }
  6. }
  7. return false
  8. }
  9. func lessThanTen(number: Int) -> Bool {
  10. return number < 10
  11. }
  12. var numbers = [20, 19, 7, 12]
  13. hasAnyMatches(numbers, lessThanTen)

闭包

函数是特殊的闭包,你可以用{}套住一个闭包而不需要指定名称,用 in 来分开参数和返回类型

[cpp] view
plain
copy

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

这个函数使得numbers里的每一个数字都变成了原来的3倍

你可以有很多种方式书写更简介的闭包,当一个闭包的类型已知,或者返回类型已知,或者都知道,你可以省略一些类型参数。单语句的闭包隐式返回唯一语句。

[cpp] view
plain
copy

  1. numbers.map({ number in 3 * number })

你也可以使用数字而不是名字来访问参数,这种方法在很短的闭包中非常有用。一个传递给函数的闭包若作为最后一个参数可以立即跟在参数后

[cpp] view
plain
copy

  1. sort([1, 5, 3, 12, 2]) { $0 > $1 }

note:函数式编程只学过一个学期,closure也掌握的不是很好,上面的式子是按从大到小排序么?希望懂函数式编程的大神解答。

对象与类

先创建一个简单的类

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

你也可以声明并定义deinit()函数创建析构方法

下面我们来讨论子类

使用:来继承

使用override关键字覆盖方法

如果不小心覆盖了一个方法却没有使用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()

可以定义变量的get和set方法

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 {
    get {
        return 3.0 * sideLength
    }
    set {
        sideLength = newValue / 3.0
    }
    }

    override func simpleDescription() -> String {
        return "An equilateral triagle with sides of length \(sideLength)."
    }
}
var triangle = EquilateralTriangle(sideLength: 3.1, name: "a triangle")
triangle.perimeter
triangle.perimeter = 9.9
triangle.sideLength

在perimeter的set方法里,新的值有一个隐式名‘newValue’,你可以显示提供名字 set(newValue : Double){}

EquilateralTriangle的初始化方法分3阶段

  1. 定义自己声明的变量的值
  2. 调用父类构造器
  3. 修改父类变量值.任意其他的方法,如set,get也能在这里调用

willset和didset可以在赋值前和赋值后调用,如下代码

class TriangleAndSquare {
    var triangle: EquilateralTriangle {
    willSet {
        square.sideLength = newValue.sideLength
    }
    }
    var square: Square {
    willSet {
        triangle.sideLength = newValue.sideLength
    }
    }
    init(size: Double, name: String) {
        square = Square(sideLength: size, name: name)
        triangle = EquilateralTriangle(sideLength: size, name: name)
    }
}
var triangleAndSquare = TriangleAndSquare(size: 10, name: "another test shape")
triangleAndSquare.square.sideLength
triangleAndSquare.triangle.sideLength
triangleAndSquare.square = Square(sideLength: 50, name: "larger square")
triangleAndSquare.triangle.sideLength

在构造square时会设置triangle的长度,在构造triangle时会设置square的长度

类里面的方法跟普通函数有一个重要的区别。普通函数的参数只能在函数作用域有效,但是类方法的参数却在你调用时也可以使用(除了第一个参数)。参数可以有二个名字,如下。第2个参数的第2个名字在函数体里使用,但是第1个名字却可以在调用时使用。

class Counter {
    var count: Int = 0
    func incrementBy(amount: Int, numberOfTimes times: Int) {
        count += amount * times
    }
}
var counter = Counter()
counter.incrementBy(2, numberOfTimes: 7)

当你与optional打交道时,可以这样书写

let optionalSquare: Square? = Square(sideLength: 2.5, name: "optional square")

当?前面的东西时nil时,所有?后面的东西都被忽略整个表达式就是nil.否则,?之前的值就被解读并且正常运行。

let sideLength = optionalSquare?.sideLength

枚举与结构体

使用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.toRaw())
        }
    }
}
let ace = Rank.Ace
let aceRawValue = ace.toRaw()

在上面的例子中,枚举的raw value时Int,所以你只需要指定第一个值Ace = 1,下面就是按顺序递增,和C++的枚举类型赋值类似。你也可以指定字符串或者浮点数为枚举类型的raw value

使用toRaw()和fromRaw()来转换raw value和枚举类型

if let convertedRank = Rank.fromRaw(3) {
    let threeDescription = convertedRank.simpleDescription()
}

枚举的成员值就是实际值,而不是其他方式写的原始值。实际上,有些情况是原始值,就是你不提供的时候。

enum Suit {
    case Spades, Hearts, Diamonds, Clubs
    func simpleDescription() -> String {
        switch self {
        case .Spades:
            return "spades"
        case .Hearts:
            return "hearts"
        case .Diamonds:
            return "diamonds"
        case .Clubs:
            return "clubs"
        }
    }
}
let hearts = Suit.Hearts
let heartsDescription = hearts.simpleDescription()

注意上面引用Hearts成员的两种方法:当赋值到 hearts 常量时,枚举成员 Suit.Hearts 通过全名引用,因为常量没有明确的类型。在 switch 中,枚举通过 .Hearts 引用,因为 self 的值是已知的。你可以在任何时候使用简化的方法。

使用struct创建结构体。struct支持很多类的特性(比如初始化和方法)。一个重要的不同之处在于struct拷贝传递(call by value),而class按引用传递(pass by reference)

struct Card {
    var rank: Rank
    var suit: Suit
    func simpleDescription() -> String {
        return "The \(rank.simpleDescription()) of \(suit.simpleDescription())"
    }
}
let threeOfSpades = Card(rank: .Three, suit: .Spades)
let threeOfSpadesDescription = threeOfSpades.simpleDescription()

一个枚举类型的实例会与一个值绑定,枚举类型相同成员的不同实例会与不同的值绑定。当创建实例的时候提供了关联的值,这个值和 raw value不同:不同实例的raw vaule是一样的.

enum ServerResponse {
    case Result(String, String)
    case Error(String)
}

let success = ServerResponse.Result("6:00 am", "8:09 pm")
let failure = ServerResponse.Error("Out of cheese.")

switch success {
case let .Result(sunrise, sunset):
    let serverResponse = "Sunrise is at \(sunrise) and sunset is at \(sunset)."
case let .Error(error):
    let serverResponse = "Failure...  \(error)"
}

success会与第一个case匹配,这就是pattern match

Swift中文教程(1)-简介,布布扣,bubuko.com

时间: 2024-10-18 07:29:29

Swift中文教程(1)-简介的相关文章

Swift中文教程(七)--协议,扩展和泛型

Protocols and Extensions 协议(接口)和扩展 Swift使用关键字protocol声明一个协议(接口): 类(classes),枚举(enumerations)和结构(structs)都可采用协议(protocol): 1 class SimpleClass: ExampleProtocol { 2 var simpleDescription: String = "A very simple class." 3 var anotherProperty: Int

Swift中文教程(一)--欢迎来到Swift的世界

原文:Swift中文教程(一)--欢迎来到Swift的世界 Apple凌晨时在WWDC发布了Swift编程语言,语法简介我很喜欢,市面上没有完整的中文教程,我在ibooks里面下载了英文原版,现在开始尝试翻译Swift.我会抽时间坚持原版翻译完,时间有限,不正之处请大家多多指教. 新建了Swifter-QQ群:362232993,同好者进. 第一章:欢迎来到Swift的世界 1,简介 Swift是一款全新的面向IOS和OS Apps的编程语言,建立在C语言和Objective-C语言的基础之上,

Swift中文教程(五)--对象和类

原文:Swift中文教程(五)--对象和类 Class 类 在Swift中可以用class关键字后跟类名创建一个类.在类里,一个属性的声明写法同一个常量或变量的声明写法一样,除非这个属性是在类的上下文里面,否则,方法和函数的写法也是这样: 1 class Shape { 2 var numberOfSides = 0 3 func simpleDescription() -> String { 4 return "A shape with \(numberOfSides) sides.&q

Swift中文教程(六)--枚举和结构

原文:Swift中文教程(六)--枚举和结构 Enumerations 枚举 使用 enum 来创建一个枚举.跟Classes(类)和其他类型的命名方式一样,枚举也可以有Method(方法). 1 enum Rank: Int { 2 case Ace = 1 3 case Two, Three, Four, Five, Six, Seven, Eight, Nine, Ten 4 case Jack, Queen, King 5 func simpleDescription() -> Stri

Swift 中文教程

Apple发布了替代oc的利器语言 Swift ,牛叉的中国开发者社区在9天的时间内就汉化了,这是多少中国开发者的福音啊,发现了之后异常兴奋,写个日志保存下,防止立马忘记: GitHub开源项目:<The Swift Programming Language>in Chinese 在线中文版: http://www.swiftguide.cn 或者 http://numbbbbb.github.io/the-swift-programming-language-in-chinese/ 中文社区

Swift中文教程(四)--函数与闭包

原文:Swift中文教程(四)--函数与闭包 Function 函数 Swift使用func关键字来声明变量,函数通过函数名加小括号内的参数列表来调用.使用->来区分参数名和返回值的类型: 1 func greet(name: String, day: String) -> String { 2 return "Hello \(name), today is \(day)." 3 } 4 greet("Bob", "Tuesday")

Swift中文教程(三)--流程控制

原文:Swift中文教程(三)--流程控制 Swift用if和switch编写条件控制语句,用for-in,for,while和do-while编写循环.条件控制语句和循环语句中,小括号是可选的,但花括号包住这个循环体是必须的: 1 let individualScores = [75, 43, 103, 87, 12] 2 var teamScore = 0 3 for score in individualScores { 4 if score > 50 { 5 teamScore += 3

Swift中文教程(二)--简单值

原文:Swift中文教程(二)--简单值 Swift使用let关键字声明常量,var关键字声明变量.常量无需在编译时指定,但至少要被赋值一次.也就是说,赋值一次多次使用: 1 var myVariable = 42 2 myVariable = 50 3 let myConstant = 42 这里的常量赋值之后值不能更改,应该提高重用性. 一个常量或变量的值与类型必须是一致的.不过,你不需要指明它的类型,因为编译器会根据你所赋的值推断它的类型,在上面的例子中,编译器会判断到myVariable

Apple Swift 中文教程 快速参考 基本语法 更新中...

总的来说,语法有java的味道,也有python的味道,还有swift自己的味道. 有些语法还是挺不伦不类的,不太好理解,即使你有几年的java或python经验,也不见得有些语法你能很轻松的看明白. 有些语法特性很好,很个性,但有些语法个人感觉乱,特性多,注意点多,还不太好理解. 慢慢学习吧... ================================================================= 值类型 Int Double Bool String 用双引号"&