Tôi đã làm việc thông qua cuốn sách Functional Programming in Swift và tôi thực sự không có cách nào tốt để hiểu sự khác biệt trong khái niệm được giới thiệu trong chương Optionals.Lập trình chức năng nhanh - "Bind tùy chọn" so với "Bản đồ tùy chọn"
Các mô hình khi làm việc với optionals có xu hướng được:
if let thing = optionalThing {
return doThing(thing)
}
else {
return nil
}
Thành ngữ này được xử lý một cách ngắn gọn với chức năng thư viện chuẩn map
map(optionalThing) { thing in doThing(thing) }
Cuốn sách này sau đó tiếp tục trên và giới thiệu các khái niệm về không bắt buộc ràng buộc, đó là nơi khả năng phân biệt của tôi bắt đầu bị phá vỡ.
Cuốn sách hướng dẫn chúng ta để xác định map
chức năng:
func map<T, U>(optional: T?, f: T -> U) -> U?
{
if let x = optional {
return f(x)
}
else {
return nil
}
}
Và cũng hướng dẫn chúng ta xác định một chức năng ràng buộc bắt buộc. Lưu ý: cuốn sách sử dụng toán tử >>=
, nhưng tôi đã chọn sử dụng hàm được đặt tên vì nó giúp tôi thấy những điểm giống nhau.
func optionalBind<T, U>(optional: T?, f: T -> U?) -> U?
{
if let x = optional {
return f(x)
}
else {
return nil
}
}
Việc triển khai cho cả hai phương pháp này trông giống hệt với tôi. Sự khác biệt duy nhất giữa hai là lập luận chức năng họ mất:
map
mất một chức năng cho phép bạn biến một T thành một UoptionalBind
mất một chức năng cho phép bạn biến một T vào một tùy chọn U
kết quả của việc "làm tổ" các cuộc gọi chức năng đau não của tôi:
func addOptionalsBind(optionalX: Int?, optionalY: Int?) -> Int?
{
return optionalBind(optionalX) { x in
optionalBind(optionalY) { y in
x + y
}
}
}
func addOptionalsMap(optionalX: Int?, optionalY: Int?) -> Int?
{
return map(optionalX) { x in
map(optionalY) { y in
x + y
}
}
}
- Chức năng
addOptionalsBind
thực hiện chính xác những gì bạn mong đợi. - Các
addOptionalsMap
chức năng thất bại trong việc biên dịch nêu:'Int ??' không thể chuyển đổi thành 'Int?'