Bạn có thể thực sự thực hiện việc này bằng cách khai báo hai toán tử riêng biệt hoạt động cùng nhau và sử dụng hàm được kết hợp cho một trong các toán tử.
Hãy tuyên bố một nhà điều hành ternary x +- y +|- z
rằng sẽ kiểm tra các dấu hiệu của giá trị ban đầu x
, và sau đó trả về giá trị thứ hai y
nếu dấu là zero hoặc tích cực và giá trị cuối cùng z
nếu dấu là tiêu cực. Tức là, chúng ta có thể viết:
let sign = -5 +- "non-negative" +|- "negative"
// sign is now "negative"
Chúng tôi sẽ bắt đầu bằng cách khai báo hai toán tử. Phần quan trọng là phải có ưu tiên cao hơn trên các nhà điều hành thứ hai - chúng tôi sẽ đánh giá phần đó đầu tiên và trả về một hàm:
infix operator +- { precedence 60 }
infix operator +|- { precedence 70 }
Sau đó xác định các chức năng - chúng tôi sẽ xác định thứ hai đầu tiên:
func +|-<T>(lhs: @autoclosure() -> T, rhs: @autoclosure() -> T)(left: Bool) -> T {
return left ? lhs() : rhs()
}
Phần quan trọng ở đây là chức năng này được curried - nếu bạn chỉ gọi nó với hai tham số đầu tiên, thay vì trả về giá trị T
, nó trả về một hàm (left: Bool) -> T
. Đó trở thành tham số thứ hai của hàm cho nhà điều hành đầu tiên của chúng tôi:
func +-<I: SignedIntegerType, T>(lhs: I, rhs: (left: Bool) -> T) -> T {
return rhs(left: lhs >= 0)
}
Và bây giờ chúng ta có thể sử dụng toán tử "ternary" của chúng tôi, như thế này:
for i in -1...1 {
let sign = i +- "" +|- "-"
println("\(i): '\(sign)'")
}
// -1: '-'
// 0: ''
// 1: ''
Lưu ý: tôi đã viết a blog post on this subject với một ví dụ khác.
Nguồn
2014-10-29 19:19:51
'func + | -' có lẽ nên sử dụng autoclosures quá, để các thông số được đánh giá lazily, như với thông thường'?: '. Ngoài ra, trong khi điều này tạo ra một cái gì đó hoạt động giống như một toán tử bậc ba, người ta không thể thực sự sử dụng '?' Và ':' vì không phải trong số đó là một mã thông báo 'operator' hợp lệ trong nhanh chóng. – bames53
Tôi vừa quay lại để chỉnh sửa! Và có, '?:' Chính nó không thể bị ghi đè. –
Ví dụ tương tự tại đây: http://www.reddit.com/r/swift/comments/2fjwav/custom_ternary_operator/ –