2014-11-14 8 views
10

Pochodzę z C++, próbuję wykonać pewne metaprogramowanie w Swift. Na przykład chciałbym zaimplementować metafunkcję, która dodaje dwie liczby. Próbowałem coś takiego:Metaprogramming in 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 
} 

To jednak nie działa: (. Lub po prostu zawiesza się, czasami) Xcode narzeka, że ​​T.Type nie posiada człon value

Jak można zaimplementować taka funkcjonalność?

+0

Hej sir ... Prawie rok później ... Czy mamy jakieś wieści o Swift i metaprogramowaniu? –

Odpowiedz

8

static przechowywane właściwości nie są (obecnie) obsługiwane na obiektach ogólnych. Kiedy umieścić swój kod w boisko, to rzeczywiście dostać ten błąd:

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

Możesz obejść, że za pomocą własności komputerowej zamiast (co mogło być to, czego chciał w pierwszej kolejności tak):

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

Uwaga: Ponieważ jest to nieruchomość komputerowej, trzeba zadeklarować value z var a nie let.

Po wprowadzeniu tych zmian println(Sum<A, B>.value) drukuje 12, jak można się spodziewać.

+0

Szczerze mówiąc, nie jestem pewien, czego chciałem (w rozumieniu semantycznym języka). Ostatecznym celem jest to, że po włączeniu wszystkich optymalizacji wartość "Sum .value" zostanie zredukowana do stałej w wynikowym kodzie binarnym. –

0

Wydaje mi się, że musisz dopasować swoje definicje i wdrożyć protokół inaczej. (nie jestem szybki programista, ale byłem uczenia się, jak pomóc ludziom na stackoverflow.)

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

Byłaś wzywając do class var, ale wtedy zdefiniował static let. Subtelna różnica, ale myślę, że tutaj ma znaczenie.

+0

Protokoły nie mogą mieć właściwości statycznych, kompilator zgłasza komunikat o błędzie, jeśli spróbujesz. –