2014-06-12 5 views
7

'u anlayan türlerle sınırlama. Artı operatörünü iki değerde kullanabilen genel bir işlev kullanmak istiyorum. Swift'de, işlevi genel olarak T + T

class funccalc { 
    func doAdd<T>(x:T,y:T) -> T { 
     return x + y 
    } 
} 
let a = funccalc() 
println(a.doAdd(1, y: 4)) 
println(a.doAdd(23.54, y:200)) 

Ben

bu yanıtında öneriyi takip etmek benim tek seçenek midir return x + y bir hata alır: https://stackoverflow.com/a/24047239/67566 ve Int olarak kendi protokolünü oluşturmak ve String operatörü tanımlarsınız?

cevap

5

Bu cevap önerilen şekilde yapmalısınız. Kullanımınız için bir protokol oluşturun ve kullanmak istediğiniz tüm sınıfları genişletin. Daha sonra, T yönteminin, yöntem imzanızda bu protokolü uyguladığından emin olun.

"Eklenebilir" protokol kullanamazsınız, çünkü hızlı bir tane yoktur. Hızlı kütüphane aslında her geçerli ekleme işlemi için bir işlev + oluşturur. Tüm bunların nerede tanımlandığını görmek için Int gibi bir şeyi tıklatın. Böyle bir şey olacaktır:

//.... 
func +(lhs: Int8, rhs: Int8) -> Int8 
func +(lhs: UInt16, rhs: UInt16) -> UInt16 
func +(lhs: Int16, rhs: Int16) -> Int16 
func +(lhs: UInt32, rhs: UInt32) -> UInt32 
func +(lhs: Int32, rhs: Int32) -> Int32 
//etc... 
+3

Başka bir yol olacağını umuyordum, sadece bu tür bir işlevsellik elde etmek için yeni bir protokol yapmak biraz can sıkıcı gibi görünüyor. Komut-clck işlemi benim için yeni, bunu denemeliyim. –

10

Sen de diğer işlevler için benzer bir ihtiyacı olabilir ve nokta türleri (veya diğer "toplanabilirdir" şeyler) Tüm tamsayı için bunları uygulamak ve kayan masif kod tekrarını neden olur.

Bir kısmi çözüm, özel olarak +, -, *, /,% protokol IntegerArithmeticType uygunluğunu gerektirecek geçerli: tanımlandıkları taşma işlemlerini uygulamak çünkü

func example<T: IntegerArithmeticType>(x: T, y: T) -> T { return x + y } 
println(example(40, 2)) // --> 42 

Bu kesirli bir tür için geçerli değildir IntegerArithmeticType gelen _IntegerArithmeticType iletişim kuralından.

Ancak belirli bir global tanımlanmış operatör fonksiyonu uygunluk için türlerini uzanan düşündüğünüzden kadar "rahatsız edici" değil:

protocol Summable { func +(lhs: Self, rhs: Self) -> Self } 

extension Int: Summable {} 
extension Double: Summable {} 
extension String: Summable {} 
// extension for any other types... you are in full control! 

Bir kez bunu, o zaman size kodunda toplanabilir kullanabilirsiniz sonsuza:

func example<T: Summable>(x: T, y: T) -> T { return x + y } 

println(example("4", "2")) // --> 42 

Gerçekten de, @connor'un işaret ettiği gibi, bu, @ Jean-PhilippePellet'in bahsettiğiniz cevabına eşdeğerdir.