转载请注明 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")
对,这就是全部代码,只有一行!!!不需要包含库,比如
简单值
let语句创建一个常量,var创建一个变量,常量值不需要在编译时(compile time)就知道,但是必须只能赋值一次
var myVariable = 42
myVariable = 50
let myConstant = 42
当然可以显示指定,如下使用了一个冒号显示声明为Double类型
let implicitInteger = 70
let implicitDouble = 70.0
let explicitDouble: Double = 70
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()
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类型的
有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,
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
var n = 2
while n < 100 {
n = n * 2
}
n
var m = 2
do {
m = m * 2
} while m < 100
m
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关键字声明函数,使用->声明函数返回类型
下面这个函数返回一个函数(接收一个int返回一个int的函数),
闭包
你可以有很多种方式书写更简介的闭包,当一个闭包的类型已知,或者返回类型已知,或者都知道,你可以省略一些类型参数。单语句的闭包隐式返回唯一语句。
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()
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阶段
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的长度
class Counter {
var count: Int = 0
func incrementBy(amount: Int, numberOfTimes times: Int) {
count += amount * times
}
}
var counter = Counter()
counter.incrementBy(2, numberOfTimes: 7)
let optionalSquare: Square? = Square(sideLength: 2.5, name: "optional square")
当?前面的东西时nil时,所有?后面的东西都被忽略整个表达式就是nil.否则,?之前的值就被解读并且正常运行。
let sideLength = optionalSquare?.sideLength
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()
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