日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

A Swift Tour, 苹果新推出的开发语言

發(fā)布時(shí)間:2024/1/8 编程问答 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 A Swift Tour, 苹果新推出的开发语言 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

蘋果近日召開(kāi)了全球開(kāi)發(fā)者大會(huì)(WWDC),推出了一種新的開(kāi)發(fā)語(yǔ)言 Swift,有人說(shuō)是用來(lái)替代Objective-C的,以下是蘋果官方文檔,第一時(shí)間整理了一下,覺(jué)得還是很有前景的,有些英文看不懂的就直接復(fù)制了,接下來(lái)的時(shí)間還是要持續(xù)關(guān)注呢。

官方鏈接:

https://developer.apple.com/library/prerelease/ios/referencelibrary/GettingStarted/LandingPage/index.html#//apple_ref/doc/uid/TP40014345


https://developer.apple.com/library/prerelease/ios/documentation/Swift/Conceptual/Swift_Programming_Language/GuidedTour.html#//apple_ref/doc/uid/TP40014097-CH2-XID_1


簡(jiǎn)介

Swift是iOS和OS X應(yīng)用編程的一種新的編程語(yǔ)言,基于C和Objective-C,卻沒(méi)有C的一些兼容約束。Swift采用了安全的編程模式和添加現(xiàn)代的功能來(lái)讓編程更加簡(jiǎn)單、靈活和有趣。界面基于廣大人民群眾愛(ài)戴的Cocoa和Cocoa Touch框架,展示了軟件開(kāi)發(fā)的新方向。

Swift已經(jīng)存在了多年。Apple基于已有的編譯器、調(diào)試器、框架作為其基礎(chǔ)架構(gòu)。通過(guò)ARC(Automatic Reference Counting,自動(dòng)引用計(jì)數(shù))來(lái)簡(jiǎn)化內(nèi)存管理。我們的框架棧則一直基于Cocoa。Objective-C進(jìn)化支持了塊、collection literal和模塊,允許現(xiàn)代語(yǔ)言的框架無(wú)需深入即可使用。

Objective-C開(kāi)發(fā)者會(huì)感到Swift的似曾相識(shí)。Swift采用了Objective-C的命名參數(shù)和動(dòng)態(tài)對(duì)象模型。提供了對(duì)Cocoa框架和mix-and-match的互操作性。基于這些基礎(chǔ),Swift引入了很多新功能和結(jié)合面向過(guò)程和面向?qū)ο蟮墓δ堋?br />

Swift對(duì)新的程序員也是友好的。他是工業(yè)級(jí)品質(zhì)的系統(tǒng)編程語(yǔ)言,卻又像腳本語(yǔ)言一樣的友好。他支持playground,允許程序員實(shí)驗(yàn)編寫Swift代碼功能并立即看到結(jié)果,而無(wú)需麻煩的構(gòu)建和運(yùn)行一個(gè)應(yīng)用。


A Swift Tour

許多編程語(yǔ)言一開(kāi)始都以hello world來(lái)開(kāi)個(gè)好頭,用Swift來(lái)寫,只有一行:

println("Hello, world")

如果你有C/C++,Objective-C的基礎(chǔ),看起來(lái)應(yīng)該會(huì)很熟悉,在Swift里,這一行就是一個(gè)完整的代碼了,不需要再引入其他的庫(kù)文件了,全局的代碼就已經(jīng)是程序的入口了,所以也不需main方法,甚至也不需要分號(hào)結(jié)尾

1.Simple Values(簡(jiǎn)單值)

使用let定義常量,var定義變量,常量并不需編譯時(shí)制定,但至少需要賦值一次,意味著只需定義一次常量,就可在所有地方使用

var myVariable = 42 myVariable = 50 let myConstant = 42

上面例子中,編譯自動(dòng)推斷myVariable是個(gè)整數(shù)類型,不需要顯示聲明,在以后的賦值也要賦予相同的類型

如果在初始化的時(shí)候沒(méi)有提供足夠的信息或根本沒(méi)有初始化賦值,可以在后面聲明,用冒號(hào)分割

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

已經(jīng)賦的值不會(huì)隱式轉(zhuǎn)換為其他類型,如果需要轉(zhuǎn)換為其他類型,需要明確寫出構(gòu)造所需類型的實(shí)例

let label = "The width is " let width = 94 let widthLabel = label + String(width)還有一種更簡(jiǎn)單的寫法在字符串中顯示變量值,變量值寫入小括號(hào)中,并在前面添加反斜線

let apples = 3 let oranges = 5 let appleSummary = "I have \(apples)apples." let fruitSummary = "I have\(apples + oranges) pieces of fruit."

用方括號(hào)[] 創(chuàng)建數(shù)據(jù)或字典,通過(guò)下標(biāo)或鍵值訪問(wèn)元素

var shoppingList =["catfish", "water", "tulips", "bluepaint"] shoppingList[1] = "bottle ofwater"var occupations = ["Malcolm": "Captain","Kaylee": "Mechanic", ] occupations["Jayne"] ="Public Relations"

如果想要?jiǎng)?chuàng)建一個(gè)空的數(shù)組或字典,使用初始化語(yǔ)句

let emptyArray = String[]() let emptyDictionary =Dictionary<String, Float>()

如果不確定類型,可以直接寫成 [] 表示空數(shù)組,[:]表示空字典

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


2.Control Flow(控制流)

使用if和switch作為條件控制,使用for-in,for,while和do-while來(lái)循環(huán),小括號(hào)不是必須的,但大括號(hào)是必須的

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

在if語(yǔ)句中,條件必須是布爾表達(dá)式,意味著 if score{…} 是錯(cuò)誤的,不能隱式的與0比較

可以同時(shí)使用if和let來(lái)防止變量值的丟失,這些值是可選的,可選值可包含一個(gè)值或一個(gè)nil來(lái)指定值是否存在,類型后面的(?) 表示值是可選的

var optionalString: String? ="Hello" optionalString == nilvar optionalName: String? = "JohnAppleseed" var greeting = "Hello!" if let name = optionalName {greeting = "Hello, \(name)" }

如果可選的值是nil,那么條件為false的語(yǔ)句將會(huì)跳過(guò),Otherwise,the optional value is unwrapped and assigned to the constant after?let, which makes the unwrapped value available insidethe block of code.

?

switch支持多種數(shù)據(jù)以及多種比較,不局限于整數(shù)和測(cè)試數(shù)相等

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

switch在匹配之后就會(huì)跳出程序塊,繼續(xù)執(zhí)行下一個(gè)邏輯代碼,而不需要break語(yǔ)句來(lái)跳出

?

使用for-in來(lái)遍歷字典中的每一個(gè)值,提供一對(duì)名稱來(lái)為每個(gè)鍵值對(duì)使用

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) ininterestingNumbers {for number in numbers {if number > largest {largest = number}} } largest

使用while來(lái)重復(fù)執(zhí)行一代碼塊直到條件成立,循環(huán)的條件可放在while末尾來(lái)確保循環(huán)至少執(zhí)行一次

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


可在循環(huán)中定義一個(gè)索引,通過(guò)..來(lái)表示索引所表示的范圍,以下兩個(gè)例子做同樣的事情

var firstForLoop = 0 for i in 0..3 {firstForLoop += i } firstForLoopvar secondForLoop = 0 for var i = 0; i < 3; ++i {secondForLoop += 1 } secondForLoo

使用 .. 構(gòu)建的范圍不包含最大值,使用 … 構(gòu)建的范圍大小值都包含

?

3.Functions and Closures(函數(shù)與閉包?)

使用func聲明一個(gè)函數(shù),調(diào)用函數(shù)的方法是使用函數(shù)名稱加括號(hào)里的參數(shù)列表,使用->分割參數(shù)名和返回的類型

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

使用tuple可以返回多個(gè)值

func getGasPrices() -> (Double,Double, Double) {return (3.59, 3.69, 3.79) } getGasPrices()

函數(shù)參數(shù)個(gè)數(shù)可以不固定,用數(shù)組表示

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

函數(shù)可以嵌套,內(nèi)嵌函數(shù)可訪問(wèn)其定義所在函數(shù)的變量

func returnFifteen() -> Int {var y = 10func add() {y += 5}add()return y } returnFifteen()

函數(shù)是第一類型的,意味著函數(shù)也可以返回另一個(gè)函數(shù)

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)

一個(gè)函數(shù)可以接收其他函數(shù)作為參數(shù)

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)

函數(shù)其實(shí)就是特殊形式的閉包,寫一個(gè)閉包不需要命名,只要加在大括號(hào)中,用in取參數(shù)和方法體的返回值

numbers.map({(number: Int) -> Int inlet result = 3 * numberreturn result })

有很多種方式來(lái)寫一些更簡(jiǎn)單的閉包,當(dāng)一個(gè)閉包的類型是已知的,比如說(shuō)對(duì)委托的回調(diào),可以省略類型的參數(shù)和返回值,單一語(yǔ)句的閉包可以直接把值返回

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

可以用數(shù)字取代名字來(lái)引用一個(gè)參數(shù),對(duì)短的閉包是很有用的,A closure passed as the last argument to a function can appearimmediately after the parentheses.

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


4.Objects and Classes(對(duì)象和類)

使用class 加類名來(lái)創(chuàng)建一個(gè)類,類中屬性的聲明和常量及變量的聲明是一樣的,除了這是在類的context中,方法和函數(shù)的聲明也是一樣的

class Shape {var numberOfSides = 0func simpleDescription() -> String {return "A shape with \(numberOfSides) sides."} }

在類名的后面添加小括號(hào)來(lái)創(chuàng)建類的實(shí)例,使用點(diǎn)操作符訪問(wèn)類的屬性和方法

var shape = Shape() shape.numberOfSides = 7 var shapeDescription =shape.simpleDescription()

使用init來(lái)創(chuàng)建一個(gè)構(gòu)造器來(lái)在創(chuàng)建實(shí)例的時(shí)候初始化

class NamedShape {var numberOfSides: Int = 0var name: Stringinit(name: String) {self.name = name}func simpleDescription() -> String {return "A shape with \(numberOfSides) sides."} }

Notice how self is used todistinguish the name property from the name argument to the initializer. Thearguments to the initializer are passed like a function call when you create aninstance of the class. Every property needs a value assigned—either in itsdeclaration (as with numberOfSides) or in the initializer (as with name).

如果需要在對(duì)象銷毀時(shí)進(jìn)行清理工作,使用deinit創(chuàng)建析構(gòu)器

子類包含其父類的名稱,以冒號(hào)分隔,在繼承標(biāo)準(zhǔn)子類時(shí)不需要聲明,所以可以根據(jù)需要包括或者忽略父類

子類的方法可通過(guò)override重載父類的方法,沒(méi)有的話會(huì)編譯錯(cuò)誤,編譯器也會(huì)檢查那些沒(méi)有被重載的方法

class Square: NamedShape {var sideLength: Doubleinit(sideLength: Double, name: String) {self.sideLength = sideLengthsuper.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()


屬性也有g(shù)etter和setter方法

class EquilateralTriangle: NamedShape {var sideLength: Double = 0.0init(sideLength: Double, name: String) {self.sideLength = sideLengthsuper.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的setter方法中,新的值得命名就是newValue,可以在set之后提供一個(gè)不沖突的名稱

注意EquilateralTriangle類構(gòu)造有三個(gè)步驟:

1.????設(shè)置屬性的值

2.????調(diào)用父類的構(gòu)造器

3.????改變父類定義的值,Any additional setup work that uses methods, getters, or setters canalso be done at this point.

?

如果不需要計(jì)算屬性但卻需要賦值后才能繼續(xù)執(zhí)行,可以使用willSet和didSet,一下例子保證三角形的邊長(zhǎng)等于矩形的邊長(zhǎng)

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

函數(shù)和類的方法有一個(gè)不同點(diǎn),函數(shù)的參數(shù)名僅用于函數(shù),方法中的參數(shù)名也可以用來(lái)調(diào)用方法(除了第一個(gè)參數(shù)),缺省時(shí),一個(gè)方法有一個(gè)同名的參數(shù),調(diào)用時(shí)就是使用參數(shù)本身,可以指定第二個(gè)名字,在方法內(nèi)部使用

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

當(dāng)使用可選值時(shí),可以像方法屬性一樣在操作符前使用問(wèn)號(hào)(?),如果值本來(lái)就是nil,那所有在?之后的代碼將會(huì)忽略,整個(gè)表達(dá)式都是nil,另外,可選值是unwrapped的,所有在?后的代碼都作為unwrapped值,在兩種情況下,真?zhèn)€表達(dá)式都是可選值

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

?

5.Enumerations and Structures(枚舉和結(jié)構(gòu))

使用enum來(lái)創(chuàng)建枚舉,跟類和其他命名一樣,枚舉也可以定義方法

enum Rank: Int {case Ace = 1case Two, Three, Four, Five, Six, Seven, Eight, Nine, Tencase Jack, Queen, Kingfunc 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()

以上例子中,初始值的枚舉類型為Int,那么只需要指定第一個(gè)初始值,其余的會(huì)自動(dòng)分配,還可以使用字符串或浮點(diǎn)數(shù)作為初始值的枚舉。

?

使用toRaw和fromRaw函數(shù)可以轉(zhuǎn)換初始值和枚舉值

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

枚舉中成員就是實(shí)際使用的值了,而不是其他方式寫的初始值,事實(shí)上,如果不提供第一個(gè)初始值的話,這種情況才是初始值

enum Suit {case Spades, Hearts, Diamonds, Clubsfunc 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()

Notice the two ways that theHearts member of the enumeration is referred to above: When assigning a valueto the hearts constant, the enumeration member Suit.Hearts is referred to byits full name because the constant doesn’t have an explicit type specified.Inside the switch, the enumeration is referred to by the abbreviated form.Hearts because the value of self is already known to be a suit. You can usethe abbreviated form anytime the value’s type is already known.

?

使用struct來(lái)創(chuàng)建結(jié)構(gòu)體,結(jié)構(gòu)體支持多個(gè)與類相同的行為,包括方法和構(gòu)造器,區(qū)別是代碼之間總是使用拷貝(值傳遞),而類是傳遞引用

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

一個(gè)枚舉的實(shí)例成員可以擁有實(shí)例的值。相同枚舉成員實(shí)例可以有不同的值。你在創(chuàng)建實(shí)例時(shí)賦值。指定值和原始值的區(qū)別:枚舉的原始值與其實(shí)例相同,你在定義枚舉時(shí)提供原始值。

例如,假設(shè)情況需要從服務(wù)器獲取太陽(yáng)升起和降落時(shí)間。服務(wù)器可以響應(yīng)相同的信息或一些錯(cuò)誤信息

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

注意日出和日落時(shí)間實(shí)際上來(lái)自于對(duì) ServerResponse 的部分匹配來(lái)選擇的

?

6.Protocols and Extensions(協(xié)議和擴(kuò)展)

使用protocol來(lái)聲明一個(gè)協(xié)議

protocol ExampleProtocol {var simpleDescription: String { get }mutating func adjust() }


協(xié)議可以被類、枚舉和結(jié)構(gòu)使用

class SimpleClass: ExampleProtocol {var simpleDescription: String = "A very simple class."var anotherProperty: Int = 69105func adjust() {simpleDescription += " Now100% adjusted."} } var a = SimpleClass() a.adjust() let aDescription = a.simpleDescriptionstruct SimpleStructure: ExampleProtocol{var simpleDescription: String = "A simple structure"mutating func adjust() {simpleDescription += " (adjusted)"} } var b = SimpleStructure() b.adjust() let bDescription = b.simpleDescription

注意,在SimpleStructure聲明中使用mutating關(guān)鍵字用于標(biāo)志這個(gè)方法的話會(huì)修改他的結(jié)構(gòu),而SimpleClass中并不需要設(shè)置mutaing標(biāo)志,因?yàn)轭愔械姆椒〞?huì)修改這個(gè)類

?

使用extension去添加已有的類型,如新方法和計(jì)算值,可以使用extension,保證任意類型具有相同的協(xié)議,不管這個(gè)類型是從框架還是類庫(kù)中來(lái)的

extension Int: ExampleProtocol {var simpleDescription: String {return "The number \(self)"}mutating func adjust() {self += 42} } 7.simpleDescription

可以像其他命令類型一樣使用協(xié)議命名,比如創(chuàng)建一個(gè)對(duì)象集合有不同的類型,但所有類型都符合同一個(gè)協(xié)議,當(dāng)使用一些協(xié)議類型的值時(shí),在協(xié)議外部定義的方法是不可用的

let protocolValue: ExampleProtocol = a protocolValue.simpleDescription // protocolValue.anotherProperty // Uncomment to see the error

Even though the variableprotocolValue has a runtime type of SimpleClass, the compiler treats it as thegiven type of ExampleProtocol. This means that you can’t accidentally accessmethods or properties that the class implements in addition to its protocolconformance.

?

7.Generics(泛型)

在尖括號(hào)里的名字就定義了一個(gè)泛型的函數(shù)或類型

func repeat<ItemType>(item:ItemType, times: Int) -> ItemType[] {var result = ItemType[]()for i in 0..times {result += item}return result } repeat("knock", 4)

泛型也可以用于函數(shù)和方法,類、枚舉及結(jié)構(gòu)

// Reimplement the Swift standardlibrary's optional type enum OptionalValue<T> {case Nonecase Some(T) } var possibleInteger:OptionalValue<Int> = .None possibleInteger = .Some(100)

在類型后面使用where來(lái)指定一個(gè)需求列表,比如指定某個(gè)泛型必須實(shí)現(xiàn)某種協(xié)議,或要求兩種類型必須相同,或要求某個(gè)類必須具有一個(gè)父類

func anyCommonElements <T, U whereT: Sequence, U: Sequence, T.GeneratorType.Element: Equatable,T.GeneratorType.Element == U.GeneratorType.Element> (lhs: T, rhs: U) ->Bool {for lhsItem in lhs {for rhsItem in rhs {if lhsItem == rhsItem {return true}}}return false } anyCommonElements([1, 2, 3], [3])

一般情況下可以忽略where,在括號(hào)后面寫一個(gè)協(xié)議名或泛型 Writing<T: Equatable> is the same as writing <T where T: Equatable>.



總結(jié)

以上是生活随笔為你收集整理的A Swift Tour, 苹果新推出的开发语言的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。