Swift vs Objective C (part 1)
Bài đăng này đã không được cập nhật trong 9 năm
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
Source: 新言語SwiftがObjective-Cよりも良いところ
All rights reserved