11/08/2018, 23:37

Swift vs Objective C (part 1)

Sau khi đọc lướt qua cuốn sách The Swift Programming Language, tôi muốn liệt kê lại những ưu điểm của Swift so với Objective-C như sau. Type Inference Khác với Objective-C, không cần phải khai báo tường minh kiểu biến thì Swift vẫn có thể tự suy được. Khi khai báo biến số thì sử dụng var, khai ...

Sau khi đọc lướt qua cuốn sách The Swift Programming Language, tôi muốn liệt kê lại những ưu điểm của Swift so với Objective-C như sau.

Type Inference

Khác với Objective-C, không cần phải khai báo tường minh kiểu biến thì Swift vẫn có thể tự suy được. Khi khai báo biến số thì sử dụng var, khai báo hằng số thì sử dụng let.

var name   = "Shinji Ikari" // tự suy là kiểu String
var age    = 14             // tự suy là kiểu Integer
let height = 141.5          // tự suy là kiểu Double

Ngoài ra, vẫn có thể khai báo tường minh kiểu biến trong Swift.

let weight:Float = 43  // kiểu Float
let favoriteWord:String  = "最低だ俺って" // kiểu String

Tuy nhiên, vẫn cần ép kiểu khi cần thiết. Ví dụ như lúc tạo chuỗi gồm 1 chuỗi khác và 1 giá trị số, phải làm như sau.

let prefix   = "iOS"
let version  = 8
let result   = prefix + String(version) // phải tự ép kiểu của version sang String

Thao tác với chuỗi đơn giản hơn ObjC

So với ObjC sử dụng các API khá phiền phức thì Swift có cú pháp hết sức đơn giản khi thao tác chuỗi, có thể sử dụng + hoặc (giá trị) để nối chuỗi. Thử check với 2 ví dụ dưới đây sẽ thấy rõ.

let firstName = "Shinji"
let lastName  = "Ikari"
let fullName  = firstName + lastName // "ShinjiIkari"
let message   = "僕は(firstName) (lastName)です。" // 僕はShinji Ikariです
NSString *firstName = @"Shinji";
NSString *lastName  = @"Ikari";
NSString *fullName  = [firstName stringByAppendingString:lastName];
NSString *message   = [NSString stringWithFormat:@"僕は%@ %@です。",firstName,lastName];

Rõ ràng là đọc source code Swift dễ dàng hơn nhiều.

Ngoài ra, () còn được sử dụng trong các trường hợp sau.

"それは(a + b)です" // Nối chuỗi bên trong chuỗi
"関数の実行結果は「( otherFunc(100) )」です" // Gọi hàm số bên trong chuỗi

Sử dụng Primitive data type cho Array, Dictionary, v.vv

Hãy nhìn đoạn code sau.

let first  = 1
let second = 2
let numbers  = [ first, second]

Thật đơn giản phải không?

Tuy vậy, ở Objective-C không bao giờ có được sự đơn giản như thế.

Nguyên nhân là vì Objective-C phân biệt Primitive data type và object (NSObject). Ví dụ như khi sử dụng giá trị số thì là NSInteger, còn object thì là NSNumber, tuỳ vào ngữ cảnh mà phán đoán sử dụng cái nào.

Đặc biệt NSArray hay NSDictionary thì bắt buộc phải xử lý là object, do vậy khi sử dụng thì rất nhiều trường hợp phải thực hiện ép kiểu.

Việc phân chia xử lý giá trị gốc với object tuỳ thuộc vào ngữ cảnh thực sự là tốn công sức. Nhiều khi nó còn là nguyên nhân gây ra bug nữa.

Ví dụ như đoạn code sau sẽ bị bug do NSInteger là giá trị gốc, ko phải là object

NSInteger first  = 1;
NSInteger second = 2;
NSArray *numbers  = @[ first, second ]

Array và Dictionary có thể mang kiểu dữ liệu

Ở Objective-C thì NSArray sử dụng kiểu id cho toàn bộ các phần tử bên trong. Mặc dù như vậy thì việc sử dụng sẽ linh hoạt hơn, tuy nhiên cũng sẽ có những trường hợp cần phải khai báo tường minh kiểu dữ liệu cho các phần tử của mảng. Khi đó thì sẽ phải thực hiện rất khó khăn ở Objective-C.

Còn ở Swift đơn giản hơn nhiều:

let nameList : String[] = ["Ikari", "Asuka", "Ayanami"]

Ngoài ra, Swift có thể sử dụng Generics.

Sử dụng câu lệnh switch với nhiều kiểu dữ liệu

Hãy check đoạn code Swift sau đây:

let company = "apple"
switch company {
case "google":
    let mobile_os = "Android"
case "apple":
    let mobile_os = "iOS"
}

Trong switch có thể sử dụng chuỗi, thật là tuyệt vời !!!

Objective-C chỉ cho phép sử dụng giá trị số. Mỗi khi muốn sử dụng NSString với câu lệnh switch, tôi đều được nghe lời khuyên "thử với if-else đi", "enum được đấy chứ", v.vv..

Ngoài ra, với where thì ở Swift, có thể thêm điều kiện nhỏ hơn vào switch.

let os_name = "FreeBSD"
switch os_name {
case let os_name where os_name.hasSuffix("BSD"):
    let comment = "os_nameの末尾にBSDがついている."
case "linux":
    let comment  = "os_nameはlinux."
default:
    let comment = "それ以外"
}

Xử lý nil

Objective-C là ngôn ngữ cho phép sử dụng nil. Chắc mọi người đều có kinh nghiệm với việc đưa giá trị nil vào các biến không nên nil rồi chứ ? Hay là phải làm quen với việc sử dụng NSAssert để check val != nil ?

Swift thì cho phép sử dụng nil hay không (có phải biến Optinal hay không) bằng dấu ? sau kiểu biến.

// Sau String thêm dấu ? thì có thể là String hoặc nil
var optionalStringFirst : String? = "Hello"
optionalStringFirst = nil // Có thể gán nil

var optionalStringSecond: String?  // Không khởi tạo tường minh thì giá trị khởi tạo là nil

Việc lựa chọn được cho phép sử dụng nil hay không sẽ giúp check được nil trước khi run app, do vậy mà tránh được bug từ sớm.

Về OptionalValue trong Swift, đã có bài viết trên viblo từ trước: Swift Optional Type

Dễ thiết kế Fluent Interface

Cách gọi method trong Objective-C có dạng [Object message] nên để tạo interface có khả năng method chain thì rất khó, thường là phải sử dụng đến Blocks. Ví dụ các thư viện fluent interface như Underscore.m, ReactiveCocoa, BoltsFramework đều sử dụng Blocks.

Swift gọi method theo dạng Object.message() nên việc sử dụng method chain sẽ dễ dàng hơn.

Part 2

Swift vs Objective C (part 2)

Source: 新言語SwiftがObjective-Cよりも良いところ

0