I'm hitting a compiler error that is best illustrated by the small code snippet below.
My goal is be able to perform addition on instances of MyEnum
directly along side CGFloat
. Now for simple cases this works perfectly fine however for more complex statements as seen in let three
example below it causes a compiler error. I understand there are several alternate architectures I can pick from including static let
or enums
with a RawValue
but that is not what I'm asking here. I'd really like to understand what is causing the compiler problem in isolated code snippet I've included below.
I have a feeling the issue is coming down the precedence (compiler can't decide to evaluate the first+second parts first or the second+third parts first) but I'm not sure. I've tried several variations including,
- Moving the operator functions to global scope.
- Moving the two operator functions that take
CGFloat
arguments to anextension CGFloat
instead.
Here is an boiled down code snippet that illustrates the issue.
enum MyEnum {
case someOption
var value: CGFloat { ... }
}
extension MyEnum {
static func + (left: MyEnum, right: MyEnum) -> CGFloat {
return left.value + right.value
}
static func + (left: MyEnum, right: CGFloat) -> CGFloat {
return left.value + right
}
static func + (left: CGFloat, right: MyEnum) -> CGFloat {
return left + right.value
}
}
let one = MyEnum.someOption + 1
let two = MyEnum.someOption + MyEnum.someOption
let three = MyEnum.someOption + MyEnum.someOption + MyEnum.someOption // fails
let four = (MyEnum.someOption + MyEnum.someOption) + MyEnum.someOption // also fails
To add more confusion if I create a completely new custom operator called •
for example and I mark it part of the AdditionPrecedence
group everything works totally fine. Ultimately I want the +
operator to make thing intuitive.
enum MyEnum {
case someOption
var value: CGFloat { ... }
}
infix operator •: AdditionPrecedence
extension MyEnum {
static func • (left: MyEnum, right: MyEnum) -> CGFloat {
return left.value + right.value
}
static func • (left: MyEnum, right: CGFloat) -> CGFloat {
return left.value + right
}
static func • (left: CGFloat, right: MyEnum) -> CGFloat {
return left + right.value
}
}
let one = MyEnum.someOption • 1
let two = MyEnum.someOption • MyEnum.someOption
let three = MyEnum.someOption • MyEnum.someOption • MyEnum.someOption // works totally fine now