Reputation: 171
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"?
Upvotes: 3
Views: 5956
Reputation: 73186
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
Upvotes: 1