Hi all,

I am fairly new to Swift, so this may very well be a simple misunderstanding on 
my part.

I was exploring the subtyping rules of Swift, especially regarding covariance. 
I came across two examples where the outcome puzzles me and I would appreciate 
if someone could explain this to me.

First I tried the covariance for the standard container types. Here is an 
excerpt from a REPL session:

Michael@carpo:~ > swift
Welcome to Apple Swift version 3.0.2 (swiftlang-800.0.63 clang-800.0.42.1). 
Type :help for assistance.
  1> open class Super {}; class Sub: Super {}
  2> print([Sub()] is [Sub])
true
  3> print([Sub()] is [Super])
true
  4> print(Array<Sub>(arrayLiteral: Sub()) is [Sub])
true
  5> print(Array<Sub>(arrayLiteral: Sub()) is [Super])
error: repl.swift:5:39: error: 'Super' is not a subtype of 'Sub'
print(Array<Sub>(arrayLiteral: Sub()) is [Super])
      ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~

Why does it matter for subtyping against [Super] whether I express an array as 
[Sub] or Array<Sub>(arrayLiteral: Sub())?

Then I tried combining array covariance with function argument type 
contravariance:

Michael@carpo:~ > swift
Welcome to Apple Swift version 3.0.2 (swiftlang-800.0.63 clang-800.0.42.1). 
Type :help for assistance.
  1> open class Super {}; class Sub: Super {}
  2> func f(_: [Super]) {}
  3> let test: ([Sub]) -> Void = f
error: repl.swift:3:29: error: cannot convert value of type '([Super]) -> ()' 
to specified type '([Sub]) -> Void'
let test: ([Sub]) -> Void = f
                            ^

Why is this assignment not possible? It works fine (as expected) when using 
plain Super and Sub instead of arrays.

Michael

_______________________________________________
swift-users mailing list
swift-users@swift.org
https://lists.swift.org/mailman/listinfo/swift-users

Reply via email to