Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Swift Custom Variable Type

Tags:

swift

For working with complex numbers, this is how I've been doing it:

import Foundation

class Complex {
    var real: Float
    var imaginary: Float
    init(re: Float, im: Float) {
        self.imaginary = im
        self.real = re
    }
    func abs() -> Float {
        return sqrtf(powf(self.real, 2) + powf(self.imaginary, 2))
    }

    func string() -> String {
        if (ceilf(self.real) == self.real) && (ceilf(self.imaginary) == self.imaginary){
            return "\(Int(self.real))+\(Int(self.imaginary))i"
        }
            return "\(self.real)+\(self.imaginary)i"
    }

    func arg() -> Float {
            return atan2f(self.imaginary, self.real)
    }
}

var someComplex = Complex(re: 2, im: 3)
var someComplexString = someComplex.string() //"2+3i"
var someComplexAbsolute = someComplex.abs() // 3.60...
var someComplexArgument = someComplex.arg() //0.98...

Now I was wondering, if there was any way to define a custom type of variable that would let me write it as someComplex: Complex = 3i for example. Is it possible to create a new type "from the ground up"?

like image 392
Pixel Avatar asked Jan 20 '26 12:01

Pixel


1 Answers

I'm slightly uncertain if this is what you're looking for, but based on your comment to the other answer

"Thanks, but what I meant was something like a custom type that would accept all floats and i for example",

you could create a wrapper that holds a single generic value, where the generic type of this value is type constrained to some protocol, to which you in turn extend the types you wish to be wrappable but the type. E.g., below allowing types Int, Float and String to be wrapped by the wrapper

protocol MyGenericTypes { }

extension Int: MyGenericTypes { }
extension Float: MyGenericTypes { }
extension String: MyGenericTypes { }

struct SomeWrapper<T: MyGenericTypes> {
    var value: T
    init(_ value: T) {
        self.value = value
    }
}

let myInt = 42
let myFloat: Float = 4.2
let myString = "forty-two"

let wrappedInt = SomeWrapper(myInt)       // T inferred as "Int"
let wrappedFloat = SomeWrapper(myFloat)   // T inferred as "Float"
let wrappedString = SomeWrapper(myString) // T ingerred as "String"

print(wrappedInt.dynamicType)    // SomeWrapper<Int>
print(wrappedFloat.dynamicType)  // SomeWrapper<Float>
print(wrappedString.dynamicType) // SomeWrapper<String>

You can naturally write generic functions allowing arguments for SomeWrapper<T> instances, type constraining T in the same fashion as in the struct definition above

func foo<T: MyGenericTypes>(bar: SomeWrapper<T>) -> () {
    print(bar.value)
}

foo(wrappedInt)    // 4.2
foo(wrappedFloat)  // 42
foo(wrappedString) // forty-two
like image 100
dfrib Avatar answered Jan 23 '26 11:01

dfrib



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!