Consider this case:
class A {
var someCommonProperty: Int = 0
}
class B {
var someCommonProperty: Int = 0
}
class C {
var someCommonProperty: Int = 0
}
protocol UnionABC {
var someCommonProperty: Int
}
extension A: UnionABC {}
extension B: UnionABC {}
extension C: UnionABC {}
===================== If we using protocol
func input(value: UnionABC) {
print(value.someCommonProperty) // Compiler will know their common
properties automatically.
if value is A {
} else if value is B {
} else if value is C {
} else {
// There are other cases? Compiler doesn't know
}
}
let a = A()
input(a)
===================== If we using union
func input(value: (A | B | C)) {
print(value.someCommonProperty) // Compiler will know their common
properties automatically.
if value is A {
} else if value is B {
} else if value is C {
} else {
// There no other cases, so the compiler trigger a warning.
}
}
let a = A()
input(a)
=====================
If using generic enum,
the compiler doesn’t know the type relation between generic union with original
type.
class A and UnionOf3<A,B,C> are totally two different types, has no
relationship.
But class A and (A | B | C) keeps a relationship.
If using union, these two cases will be allowed:
let a = A()
let union: (A|B|C) = a // Automatically wrap.
a == union // Can be compared, Yes
sub-typing:
var fn0: A->Void = {print(v0)}
var fn1: (A|B)->Void = {print(v0)}
fn0 = fn1 // Original Type and Union Type has a sub-typing relationship, OK
var fn2: (A|B|C)->Void = {print($0)}
fn0 = fn2 // OK
fn1 = fn2 // OK
> 在 2016年5月16日,18:17,Austin Zheng <[email protected]> 写道:
>
> This doesn't explain how I can use 'value' once an A() is passed into the
> function:
>
> func input(value: (A | B | C)) {
>
> }
>
> If A, B, and C are not related via protocol or class inheritance, then there
> is almost nothing you can do with value. Otherwise you still need to test
> against the concrete type using a case statement or a if-else ladder.
>
> The other 'gain' is being able to call 'input(A())', rather than
> 'input(.caseA(A()))'. I agree that the first form is prettier than the second
> one. I also think you could make the language pervasively prettier and more
> expressive by allowing for all sorts of implicit conversions. At some point
> clarity at the point of use beats conciseness, especially when code within a
> complex codebase needs to be maintained.
>
> I understand that this is largely a matter of style - different people value
> different things, and that's wonderful. I welcome a formal proposal submitted
> to the swift-evolution process, and if one appears I'm happy to consider it
> in more detail and argue for or against it based on that.
>
> Austin
>
>
>
> On Sun, May 15, 2016 at 3:34 AM, Cao Jiannan <[email protected]
> <mailto:[email protected]>> wrote:
> for example, there is a method input union of 3 types: A, B, C,
>
> This is the three class.
>
> class A {}
>
> class B {}
>
> class C {}
>
> This is how it implemented under Swift 2:
>
> enum UnionABC {
> case classA(A)
> case classB(B)
> case classC(C)
> }
>
> func input(value: UnionABC) {
>
> }
>
> let a = A()
> let b = B()
> let c = C()
> input(UnionABC.classA(a))
>
>
> It needs announce all the cases and name each cases and cannot use class
> names as their case names.
>
> what about using union? It is more easy and rational.
>
>
> func input(value: (A | B | C)) {
>
> }
>
> let a= A()
> input(a)
>
> Or you can implement it with protocol and extension, but compiler will not
> know how many cases it should have.
>
>
> protocol UnionABC {
>
> }
>
> extension A: UnionABC {}
> extension B: UnionABC {}
> extension C: UnionABC {}
>
>
> func input(value: UnionABC) {
> if value is A {
>
> } else if value is B {
>
> } else if value is C {
>
> } else {
> // There are other cases? Compiler doesn't know
> }
> }
>
> let a = A()
> input(a)
>
>
>
>> 下面是被转发的邮件:
>>
>> 发件人: [email protected] <mailto:[email protected]>
>> 主题: 回复: [swift-evolution] Union instead of Optional
>> 日期: 2016年5月15日 GMT+8 18:00:55
>> 收件人: Austin Zheng <[email protected] <mailto:[email protected]>>
>>
>>
>> Enum and Union are two things.
>>
>> If you use Enum to implement Union, you should announce it with case name.
>>
>> Another issue using enum instead of union is that, union can combine types
>> as many as possible, you just write ( A | B | C ... | Z), but for enum, you
>> should carefully announce it for each case.
>>
>> 在 2016年5月15日,15:22,Austin Zheng <[email protected]
>> <mailto:[email protected]>> 写道:
>>
>>> In addition, not everything in Swift can be modeled in terms of inheritance
>>> relationships.
>>>
>>> I'm a little curious as to why union types keep on coming up, when enums
>>> can do everything they can and much more (methods, constraints on generic
>>> types, conformance to protocols).
>>>
>>> Austin
>>>>> [email protected] <mailto:[email protected]>
>>>>> https://lists.swift.org/mailman/listinfo/swift-evolution
>>>>> <https://lists.swift.org/mailman/listinfo/swift-evolution>
>>>>
>>>> _______________________________________________
>>>> swift-evolution mailing list
>>>> [email protected] <mailto:[email protected]>
>>>> https://lists.swift.org/mailman/listinfo/swift-evolution
>>>> <https://lists.swift.org/mailman/listinfo/swift-evolution>
>
>
_______________________________________________
swift-evolution mailing list
[email protected]
https://lists.swift.org/mailman/listinfo/swift-evolution