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

Reply via email to