Alex
Alex

Reputation: 541

checking if generic Type is of s specific Type inside class

Assuming we have the following protocol and class:

protocol Numeric { }
extension Float: Numeric {}
extension Double: Numeric {}
extension Int: Numeric {}

class NumericProcessor<T:Numeric> {
    var test:T
    func processString(stringValue: String?)
        if T is Double {
            test = Double(stringValue)
        }
    }
}

What i want is to convert the String to the spesific T:Numeric.

test = T(stringValue)

will not work although Double(stringValue), Float(stringValue) would work.

if T is Double {
   test = Double(stringValue)
}

Does not work because T is Double can`t be asked. How could i possibly approach this problem in a generic Numeric class?

Upvotes: 3

Views: 709

Answers (2)

t4nhpt
t4nhpt

Reputation: 5302

What about this:

protocol Numeric { }
extension Float: Numeric {}
extension Double: Numeric {}
extension Int: Numeric {}

class NumericProcessor<T:Numeric> {
    var test:T?
    func processString(stringValue: String?)
        if T.self == Swift.Double {
            test = Double(stringValue) as? T
        } else if T.self == Swift.Float {
            test = Float(stringValue) as? T
        }
    }
}

Upvotes: 0

JeremyP
JeremyP

Reputation: 86651

Edit

I'm an idiot. You can add an initialiser to a protocol

protocol Numeric
{
    init?(_ s: String)
}

extension Float: Numeric{}

class NumericProcessor<T:Numeric>
{
    var test:T?

    func processString(stringValue: String?)
    {
        test = T(stringValue!)
    }
}

let n = NumericProcessor<Float>()

n.processString("1.5")
print("\(n.test)") // prints "Optional(1.5)"

Original not so good answer

You can add a static function to the protocol to do the conversion.

protocol Numeric
{
    static func fromString(s: String) -> Self?
}

extension Float: Numeric
{
    static func fromString(s: String) -> Float?
    {
        return Float(s)
    }
}

// Same pattern for Int and Double

class NumericProcessor<T:Numeric>
{
    var test:T?

    func processString(stringValue: String?)
    {
        test = T.fromString(stringValue!)
    }

}

let n = NumericProcessor<Float>()

n.processString("1.5")
print("\(n.test)") // prints "Optional(1.5)"

Upvotes: 2

Related Questions