程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C >> C語言入門知識 >> Swift 與Objective

Swift 與Objective

編輯:C語言入門知識

Swift已經推出了一段時間了,今天來總結一下Swift與Objective-c(以下簡稱OC)的語法有哪些不同。

1.常量與變量:

在Swift中定義常量和變量很簡單,常量使用let關鍵字,變量使用var關鍵字。

?var numberOfRows = 30
let maxNumberOfRows = 100

在OC中我們聲明一個變量的時候需要指定數據類型:

const int count = 10;
double price = 23.55;
NSString *myMessage = @"Objective-C is not dead yet!";

但是在Swift中我們不用,雖然Swift是強類型語言,但是它可以根據賦值進行類型推斷:

et count = 10
// count會被識別為Int
var price = 23.55
// price會被識別為Double
var myMessage = "Swift is the future!"
// myMessage會被識別為String

當然在Swift中寫上變量名也不會有任何問題:

var myMessage : String = "Swift is the future!"

2.Swift中不用再寫分號了!

在OC中你需要在每一句的後面寫上“;”以表達結束,不然會報錯,在Swift中你不需要再寫分號了,當然你寫上也沒有問題。

var myMessage = "No semicolon is needed"

3.String

在Swift中字符串的類型是String,不論你定義的是常量字符串還是變量字符串。

?let dontModifyMe = "You cannot modify this string"
var modifyMe = "You can modify this string"

在OC中你需要使用NSString和NSMutableString來區分字符串是否可以被修改。

在Swift中連接兩個字符串組成新字符串非常方便,使用“+”:

let firstMessage = "Swift is awesome. "
let secondMessage= "What do you think?"
var message = firstMessage + secondMessage
println(message)

println是Swift中一個全局的打印方法。

在OC中我們使用stringWithFormat方法:

NSString *firstMessage = @"Swift is awesome. ";
NSString *secondMessage = @"What do you think?";
NSString *message = [NSString stringWithFormat:@"%@%@", firstMessage, secondMessage];
NSLog(@"%@", message);

在OC中要判斷兩個字符串是否相同你不能用“==”,你需要使用方法isEqualToString方法,但是在Swift中你可以使用“==”來判斷字符串是否相同。

?var string1 = "Hello"
var string2 = "Hello"
if string1 == string2 {
    println("Both are the same")
} 



4.Array數組

數組的用法Swift和OC差不多,我們來看示例:

在OC中:

?NSArray *recipes = @[@"Egg Benedict", @"Mushroom Risotto", @"Full Breakfast", @"Hamburger",
@"Ham and Egg Sandwich"];

在Swift中:

?var recipes = ["Egg Benedict", "Mushroom Risotto", "Full Breakfast", "Hamburger", "Ham and Egg
Sandwich"]

在OC中你可以向NSArray和NSMutableArray中插入任意類型的參數,但是在OC中只能插入相同的參數。

和NSArray相似,Swift中的Array也有很多方法,比如count方法返回數組中的元素個數:

?var recipes : [String] = ["Egg Benedict", "Mushroom Risotto", "Full Breakfast", "Hamburger",
"Ham and Egg Sandwich"]
?var numberOfItems = recipes.count
// recipes.count will return 5


在OC中你使用NSMutableArray中的方法addObject來增加數組中的元素,Swift中的方法更簡單,你可以使用“+=”,比如:

recipes += ["Thai Shrimp Cake"]
不過請注意這個方法是數組間的,如果一個單個元素要加入數組中請在元素外面增加[]。

要取出或者替換數組中的元素,使用索引,這點跟OC中相同:

?var recipeItem = recipes[0]
recipes[1] = "Cupcake"

在Swift中可以使用Range來表示范圍:比如
recipes[1...3] = ["Cheese Cake", "Greek Salad", "Braised Beef Cheeks"]
這裡替換的是recipes中的第二到第四個元素。

5.Dictionary字典

字典是一種集合類型,由鍵值對組成,這一點和OC中的NSDictionary很類似,請看示例:

OC中:

?NSDictionary *companies = @{@"AAPL" : @"Apple Inc", @"GOOG" : @"Google Inc", @"AMZN" :
@"Amazon.com, Inc", @"FB" : @"Facebook Inc"};

Swift中:

?var companies = ["AAPL" : "Apple Inc", "GOOG" : "Google Inc", "AMZN" : "Amazon.com, Inc",
"FB" : "Facebook Inc"]
你也可以聲明它的字典類型:

?var companies: Dictionary = ["AAPL" : "Apple Inc", "GOOG" : "Google Inc",
"AMZN" : "Amazon.com, Inc", "FB" : "Facebook Inc"]

要遍歷一個字典,需要使用元組來保存每一次循環的字典中的信息:

for (stockCode, name) in companies {
    println("\(stockCode) = \(name)")
}

你也可以單獨遍歷字典中的鍵或者值:

for stockCode in companies.keys {
    println("Stock code = \(stockCode)")
}
for name in companies.values {
    println("Company name = \(name)")
}

如果想給字典添加新的鍵值對,那麼使用如下語句:

companies["TWTR"] = "Twitter Inc"

6.Class類

在OC中創建類的話,會得到兩個文件,一個接口文件(.h文件)和一個實現文件(.m文件)。

而在Swift中生成類只有一個文件.swift文件。

示例:

class Recipe {
    var name: String = ""
    var duration: Int = 10
    var ingredients: [String] = ["egg"]
}

在上面的示例中我們創建了一個Recipe類,裡面有三個屬性,並且都聲明了類型,做了初始化。在Swift中類在初始化的時候它的屬性必須都被初始化。如果你不想設置某個屬性的默認值的話,使用?把它加入可選鏈中:

class Recipe {
    var name: String?
    var duration: Int = 10
    var ingredients: [String]?
}
這樣當你創建一個類的實例的時候:

var recipeItem = Recipe()

這些可選鏈中的屬性的初始值是nil。你可以給它們賦值:

recipeItem.name = "Mushroom Risotto"
recipeItem.duration = 30
recipeItem.ingredients = ["1 tbsp dried porcini mushrooms", "2 tbsp olive oil", "1 onion,
chopped", "2 garlic cloves", "350g/12oz arborio rice", "1.2 litres/2 pints hot vegetable
stock", "salt and pepper", "25g/1oz butter"]

類可以繼承父類和遵守協議,示例:

OC中:

?@interface SimpleTableViewController : UIViewController 

Swift中:

class SimpleTableViewController : UIViewController, UITableViewDelegate, UITableViewDataSource

7.Methods方法

Swift允許你在類、結構體和枚舉中創建方法。

下面是一個沒有參數和返回值的方法:

class TodoManager {
    func printWelcomeMessage() {
        println("Welcome to My ToDo List")
    }
}

在OC中調用一個方法的格式如下:

todoManager printWelcomeMessage];

在Swift中調用一個方法的格式如下:

todoManager.printWelcomeMessage()

如果要建立一個帶參數和返回值的方法,格式如下:

class TodoManager {
    func printWelcomeMessage(name:String) -> Int {
        println("Welcome to \(name)'s ToDo List")
return 10 }
}

"->"用來指示方法的返回值類型。

你可以這樣調用上面的方法:

var todoManager = TodoManager()
let numberOfTodoItem = todoManager.printWelcomeMessage("Simon")
println(numberOfTodoItem)


8.Control Flow控制流

Swift中的控制流和循環頗有C語言的風格。

8.1for循環

for循環使用 for - in的結構,並且可以和Range(...或者..<)配合使用:

for i in 0..<5 {
    println("index = \(i)")
}

會在控制台輸出:

index = 0

index = 1

index = 2

index = 3

index = 4



如果我們使用...這是個閉集合,結果會返回:

index = 0

index = 1

index = 2

index = 3

index = 4

index = 5

如果你想用c中的結構也是可以的:

for var i = 0; i < 5; i++ {
    println("index = \(i)")
}

只不過for後面不用寫括號了。


8.2 if-else結構

和OC中很像,只不過Swift中更簡單一些,條件語句不需要寫在括號中:

var bookPrice = 1000;
if bookPrice >= 999 {
    println("Hey, the book is expensive")
} else {
    println("Okay, I can affort it")
}

8.3 switch結構

Switch中的switch結構擁有非常強大的功能。

示例:

switch recipeName {
    case "Egg Benedict":
        println("Let's cook!")
    case "Mushroom Risotto":
        println("Hmm... let me think about it")
    case "Hamburger":
        println("Love it!")
    default:
}
println("Anything else")

首先Swift中的switch中可以控制字符串,OC中的NSString是不能被switch控制的,在OC中要實現類似功能你只能使用if-else。

另外你可以看到在每個case中我們都沒有寫break,在OC中你必須在每個case中寫break,否則在當前case結束後會進入下一個case,在Swift中當前case被執行後就會自動跳出switch,如果需要進入下一個case,添加fallthrough語句。

最後,switch的case中可以包含Range操作:

var speed = 50
switch speed {
case 0:
    println("stop")
case 0...40:
    println("slow")
case 41...70:
    println("normal")
case 71..<101:
    println("fast")
default:
    println("not classified yet")
}

9.Tuple元組

元組類型在OC中是沒有的,它可以包含多種不同的數據類型,你可以把它用作方法的返回值,這樣就可以用一個元組來代替返回一個復雜的對象了。例如:

let company = ("AAPL", "Apple Inc", 93.5)

你可以把元組company中的值取出來,用法如下:

let (stockCode, companyName, stockPrice) = company
println("stock code = \(stockCode)")
println("company name = \(companyName)")
println("stock price = \(stockPrice)")

或者company.0、company.1這樣的方法也能取到值,更好的做法是在定義元組的時候給每個元素起個名字:

let product = (id: "AP234", name: "iPhone 6", price: 599)
println("id = \(product.id)")
println("name = \(product.name)")
println("price = USD\(product.price)")

下面是一個把元組作為返回類型的例子:

class Store {
    func getProduct(number: Int) -> (id: String, name: String, price: Int) {
        var id = "IP435", name = "iMac", price = 1399
        switch number {
            case 1:
                id = "AP234"
                name = "iPhone 6"
                price = 599
        case 2:
            id = "PE645"
            name = "iPad Air"
            price = 499
default:break }
        return (id, name, price)
    }
}


調用:

let store = Store()
let product = store.getProduct(2)
println("id = \(product.id)")
println("name = \(product.name)")
println("price = USD\(product.price)")

10.Optional可選型

10.1可選型

可選型通常用在變量之中,可選型的默認值是nil。如果你給一個非可選型的變量賦值nil會報錯:

?var message: String = "Swift is awesome!" // OK
message = nil // compile-time error

當你的類中的屬性沒有全部初始化的時候會報錯:

class Messenger {
    var message1: String = "Swift is awesome!" // OK
    var message2: String // compile-time error
}

在OC中當你給變量賦值為nil或者沒有初始化屬性的時候,你是不會收到一個編譯時錯誤的:

NSString *message = @"Objective-C will never die!";
message = nil;
class Messenger {
    NSString *message1 = @"Objective will never die!";
    NSString *message2;}

但這不代表你不可以在Swift使用沒有初始化的屬性,我們可以使用?來表示這是一個可選型的變量:

class Messenger {
    var message1: String = "Swift is awesome!" // OK
    var message2: String? // OK
}

10.2那麼我們為什麼要用可選型呢?

Swift語言設計的時候有很多安全方面的考慮,可選型表示了Swift是一門類型安全的語言,從上面的例子中你可以看到Swift中的可選型會在編譯時就去檢查某些可能發生在運行時的錯誤。

考慮下面的OC中的方法:

- (NSString *)findStockCode:(NSString *)company {
    if ([company isEqualToString:@"Apple"]) {
        return @"AAPL";
    } else if ([company isEqualToString:@"Google"]) {
        return @"GOOG";
    }
return nil; }

這個方法用來判斷輸入的字符串是不是Apple和Google,如果是其他的話返回nil。

假設我們在類中定義這個方法,並且在類中使用它:

NSString *stockCode = [self findStockCode:@"Facebook"]; // nil is returned
?NSString *text = @"Stock Code - ";
NSString *message = [text stringByAppendingString:stockCode]; // runtime error
NSLog(@"%@", message);


這段代碼是可以通過編譯的,但是會在運行時發生錯誤,原因就是方法中傳入FaceBook返回了nil。

上面OC中的代碼我們在Swift中的話是這樣寫的:

func findStockCode(company: String) -> String? {
   if (company == "Apple") {
      return "AAPL"
   } else if (company == "Google") {
      return "GOOG"
   }
return nil }
var stockCode:String? = findStockCode("Facebook")
let text = "Stock Code - "
let message = text + stockCode  // compile-time error
println(message)



這段代碼不能通過編譯,可以避免運行時的錯誤了。顯而易見,可選型的應用可以提高代碼的質量。

10.3解包可選型

在上面我們已經看到了可選型的用法,那麼我們如何判斷一個可選型的變量有值還是為nil呢?

示例:

var stockCode:String? = findStockCode("Facebook")
let text = "Stock Code - "
if stockCode != nil {
    let message = text + stockCode!
    println(message)
}

很像OC中的配對,我們使用if判斷語句來做可選型的空值判斷。一旦我們知道可選型肯定有值的時候,我們可以使用強制拆封(或者叫解包),也就是在變量名後面加一個感歎號來取得變量的值。

如果我們忘記做空值判斷會怎樣?你進形了強制拆封所以不會發生編譯時錯誤

var stockCode:String? = findStockCode("Facebook")
let text = "Stock Code - "
let message = text + stockCode!  // runtime error

會發生運行時錯誤,錯誤提示:

Can’t unwrap Optional.None


10.4可選綁定

除了強制拆封,可選綁定是一個更簡單更好的做法。你使用if - let結構的可選綁定來判斷一個變量是不是空值

示例:

var stockCode:String? = findStockCode("Facebook")
let text = "Stock Code - "
if let tempStockCode = stockCode {
    let message = text + tempStockCode
    println(message)
}

if let的意思是如果stockCode有值,那麼解包它,並且把它賦給一個臨時變量tempStockCode,並且執行下面大括號中(條件塊)的代碼,否則跳過大括號中的代碼。

因為tempStockCode是一個新的常量,你不必再使用!來獲取它的值。

你可以簡化這個過程:

let text = "Stock Code - "
if var stockCode = findStockCode("Apple") {
    let message = text + stockCode
    println(message)
}

我們把stockCode的定義放到if中,這裡stockCode不是可選型,所以在下面的大括號中也不用再使用!如果它是nil,那麼大括號中的代碼就不會執行。

10.5可選鏈

我們有一個類Code,裡面有兩個屬性code和price,它們的類型是可選型。把上面示例中的stockCode方法的返回值由String改為返回一個Code類型。

class Stock {
    var code: String?
    var price: Double?
}
func findStockCode(company: String) -> Stock? {
    if (company == "Apple") {
        let aapl: Stock = Stock()
        aapl.code = "AAPL"
        aapl.price = 90.32
return aapl
    } else if (company == "Google") {
        let goog: Stock = Stock()
        goog.code = "GOOG"
        goog.price = 556.36
return goog }
return nil }

現在我們計算買了100個蘋果需要多少錢:

if let stock = findStockCode("Apple") {
    if let sharePrice = stock.price {
        let totalCost = sharePrice * 100
        println(totalCost)
    }
}

因為findStockCode的返回值是可選值,我們使用可選綁定來判斷,但是Stock的price屬性也是可選的,所以我們又用了一個可選綁定來判斷空值。

上面的代碼運行沒有問題,不用if let我們有更簡單的辦法,你可以把上面的代碼改成可選鏈的操作,這個特性允許我們把多個可選類型用?連接,做法如下:

if let sharePrice = findStockCode("Apple")?.price {
    let totalCost = sharePrice * 100
    println(totalCost)
}





  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved