2015-05-28 6 views
6

Ich frage mich, ob es ein einfacher Weg ist, diese beiden initializers als Gattungs InitializerDo Int und Doppel eine gemeinsame Elternklasse in Swift

public required init(_ value : Double) { 
    super.init(value: value, unitType: unit) 
} 

public required init(_ value : Int) { 
    let v = Double(value) 
    super.init(value: v, unitType: unit) 
} 

So etwas zu schreiben:

public init<T>(_value : T) { 
    let v = Double(T) 
    super.init(value: v, unitType: unit) 
} 

(was natürlich nicht kompiliert)

Ich habe den Code von Int und Double durchgesehen und vermisse jede echte Sache, die sie miteinander verbindet.

+1

Sie teilen viele Protokolle gemeinsam - sie sind beide "AbsoluteValuable" , 'Comparable',' IntegerLiteralConvertible'. Schauen Sie sich [SwiftDoc] (http://swiftdoc.org/type/Double/hierarchy/) an, um sich einen Überblick über die gesamte Hierarchie zu verschaffen. Um diese Frage wirklich zu beantworten, benötigt man mehr Informationen über die Klasse, die man initialisiert - es hängt wirklich davon ab, was "value:' in 'super.init' ist. –

+0

Es erfordert ein Double, um zu initialisieren, aber ich dachte, ich könnte jede Klasse (einschließlich) Doppel in einem Double wickeln und es sollte funktionieren. – Jeef

+1

'Int' und' Double' sind Strukturen, keine Klassen – newacct

Antwort

8

im Swift-Header Werfen Sie einen Blick:

extension String : StringInterpolationConvertible { 
    init(stringInterpolationSegment expr: String) 
    init(stringInterpolationSegment expr: Character) 
    init(stringInterpolationSegment expr: UnicodeScalar) 
    init(stringInterpolationSegment expr: Bool) 
    init(stringInterpolationSegment expr: Float32) 
    init(stringInterpolationSegment expr: Float64) 
    init(stringInterpolationSegment expr: UInt8) 
    init(stringInterpolationSegment expr: Int8) 
    init(stringInterpolationSegment expr: UInt16) 
    init(stringInterpolationSegment expr: Int16) 
    init(stringInterpolationSegment expr: UInt32) 
    init(stringInterpolationSegment expr: Int32) 
    init(stringInterpolationSegment expr: UInt64) 
    init(stringInterpolationSegment expr: Int64) 
    init(stringInterpolationSegment expr: UInt) 
    init(stringInterpolationSegment expr: Int) 
} 

Ähnlich:

func +(lhs: UInt8, rhs: UInt8) -> UInt8 
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 
func +(lhs: UInt64, rhs: UInt64) -> UInt64 
func +(lhs: Int64, rhs: Int64) -> Int64 
func +(lhs: UInt, rhs: UInt) -> UInt 
func +(lhs: Int, rhs: Int) -> Int 
func +(lhs: Float, rhs: Float) -> Float 
func +(lhs: Double, rhs: Double) -> Double 
func +(lhs: Float80, rhs: Float80) -> Float80 

Wenn es möglich wäre eine generische Funktion für alle diese verschiedenen numerischen Typen würden sie zu schreiben, hab es sicher getan. So ist die Antwort auf Ihre Frage muss Nr sein

(Und in jedem Fall können sie kaum eine Klasse Elternteil, da sie nicht Klassen. Sie sind structs.)

Nun, natürlich Wenn nur Int und Double in Frage sind, Sie könnten Int und Double erweitern, um ein gemeinsames Protokoll zu übernehmen und dieses Protokoll den erwarteten Typ ...

+3

Dies ist eine irreführende Antwort. Das hängt vom Anwendungsfall ab. Während diese Typen einen eigenen Additionsoperator benötigen, ist es durchaus möglich, breite Operationsklassen über alle Ganzzahlen hinweg zu definieren, wie zum Beispiel 'func sum (seq: S) -> S.Generator.Element {return reduce (seq, 0) {$ 0 + $ 1}} '. Allerdings gibt es nur wenige Protokolle, die eine Brücke zwischen Integer und Float bilden. –

+0

@AirspeedVelocity Eigentlich habe ich nur darauf gewartet, dass du mitkommst und die richtige Antwort gibst. Bitte gib es! – matt