2014-11-14 19 views
10

Đến từ C++, tôi đang cố gắng thực hiện một số phép lập trình meta trong Swift. Ví dụ, tôi muốn thực hiện một metafunction thêm hai số. Tôi đã thử một cái gì đó như thế này:Lập trình meta trong Swift

protocol IntWrapper { 
    class var value: Int { get } 
} 

struct A: IntWrapper { 
    static let value = 5 
} 

struct B: IntWrapper { 
    static let value = 7 
} 

struct Sum<T: IntWrapper, U: IntWrapper>: IntWrapper { 
    static let value = T.value + U.value 
} 

này, tuy nhiên, không hoạt động: (. Hay chỉ bị treo, đôi khi) Xcode phàn nàn rằng T.Type không có thành viên value

Làm thế nào có thể thực hiện chức năng như vậy?

+0

Hey sir´s .... Gần một năm sau ... Chúng ta có tin tức gì về Swift và Metaprogramming không? –

Trả lời

8

static thuộc tính được lưu trữ hiện không được hỗ trợ trên các đối tượng chung. Khi tôi đặt mã của bạn trong một sân chơi, tôi thực sự nhận được lỗi này:

Playground execution failed: <EXPR>:23:5: error: static variables not yet supported in generic types 
    static let value = T.value + U.value 
    ^~~~~~ 

Bạn có thể khắc phục điều đó bằng cách sử dụng một tài sản tính thay vì (có thể có được những gì bạn muốn ở nơi đầu tiên anyway):

struct Sum<T: IntWrapper, U: IntWrapper>: IntWrapper { 
    static var value: Int { 
     return T.value + U.value 
    } 
} 

Lưu ý: Kể từ đó là một tài sản tính, bạn cần phải khai báo với valuevar và không let.

Với những thay đổi đó, println(Sum<A, B>.value) in 12 như bạn mong muốn.

+0

Thành thật mà nói, tôi không thực sự chắc chắn những gì tôi muốn (trong ý nghĩa ngữ nghĩa ngôn ngữ). Mục tiêu cuối cùng là khi tất cả các tối ưu hóa được kích hoạt, 'Sum .value' sẽ được giảm xuống một hằng số trong mã nhị phân kết quả. –

0

Dường như với tôi rằng bạn cần phải khớp các định nghĩa của mình và triển khai giao thức khác nhau. (Tôi không phải là một nhà phát triển nhanh chóng, nhưng tôi đã được học tập như tôi giúp mọi người trên stackoverflow.)

protocol IntWrapper { 
    static var value : Int { get } 
} 
struct A: IntWrapper { 
    static var value : Int { get { 5 } } 
} 

Bạn đã kêu gọi một class var, nhưng sau đó bạn định nghĩa một static let. Sự khác biệt tinh tế, nhưng tôi nghĩ nó quan trọng ở đây.

+0

Giao thức không thể có các thuộc tính tĩnh, trình biên dịch sẽ gửi thông báo lỗi nếu bạn thử. –

Các vấn đề liên quan