Re: Returning a more specific type from a subclassed method?

Previous Topic
 
classic Classic list List threaded Threaded
1 message Options
Reply | Threaded
Open this post in threaded view
|

Re: Returning a more specific type from a subclassed method?

Jeremy Pereira
Actually, a String is not an Any in the sense of being a subclass.  

I'm not saying the current behaviour is right, I'm just theorising about why it might be so.

On 22 Jul 2014, at 17:21, Ben Gollmer <[hidden email]> wrote:

> I'm not sure why that is important -- a String is still an Any.
>
> I tried declaring Option.value() as returning AnyObject / AnyObject? and StringOption.value() as returning NSString / NSString?, but saw no change in behavior.
>
>
> --
> Ben
>
> On Jul 22, 2014, at 9:34 AM, Jeremy Pereira <[hidden email]> wrote:
>
>> Also, String is a struct, so it doesn't have superclasses.
>>
>>
>> On 22 Jul 2014, at 15:15, Ben Gollmer <[hidden email]> wrote:
>>
>>> That sounds plausible, but changing the return types to non-Optional results in the same behavior for all three implementations of StringOption.value().
>>>
>>> --
>>> Ben
>>>
>>> On Jul 22, 2014, at 7:32 AM, Jeremy Pereira <[hidden email]> wrote:
>>>
>>>>
>>>> My guess is that that String? is not a subclass of Any?
>>>>
>>>> Type? is shorthand for Optional<Type>.  I don't see why the compiler would necessarily regard Optional<String> as being a subclass of Optional<Any> - after all, actually it isn't.
>>>>
>>>> On 19 Jul 2014, at 20:15, Ben Gollmer <[hidden email]> wrote:
>>>>
>>>>> According to http://nomothetis.svbtle.com/type-variance-in-swift, function return types are covariant (e.g. it's fine to return a more specific type than required), but that doesn't seem to extend to methods.
>>>>>
>>>>> For example, given this code:
>>>>>
>>>>>> class Option {
>>>>>> func value() -> Any? {
>>>>>> return nil
>>>>>> }
>>>>>> }
>>>>>>
>>>>>> class StringOption: Option {
>>>>>> // Various options for implementing value() listed below
>>>>>> }
>>>>>>
>>>>>> let o1 = Option()
>>>>>> let o2 = StringOption()
>>>>>>
>>>>>> for opt in [o1, o2] {
>>>>>> println(opt.value())
>>>>>> }
>>>>>>
>>>>>> if o2.value()!.hasPrefix("T") {
>>>>>> println("That worked")
>>>>>> }
>>>>>
>>>>> This causes the compiler to complain "Method does not override any method from its superclass":
>>>>>
>>>>>> override func value() -> String? {
>>>>>> return "TEST"
>>>>>> }
>>>>>
>>>>> This compiles and runs, but unexpectedly prints "nil, nil" from the for loop:
>>>>>
>>>>>> func value() -> String? {
>>>>>> return "TEST"
>>>>>> }
>>>>>
>>>>> And this loses type information, causing a compiler error on the hasPrefix() call; "'Any' does not have a member named 'hasPrefix'":
>>>>>
>>>>>> override func value() -> Any? {
>>>>>> return "TEST"
>>>>>> }
>>>>>
>>>>> Is this expected behavior, or a bug? The equivalent Obj-C code does behave as I'd expect.
>>>>>
>>>>>> #import <Foundation/Foundation.h>
>>>>>>
>>>>>> @interface Option: NSObject
>>>>>> - (id)value;
>>>>>> @end
>>>>>>
>>>>>> @implementation Option
>>>>>> - (id)value {
>>>>>> return nil;
>>>>>> }
>>>>>> @end
>>>>>>
>>>>>> @interface StringOption: Option
>>>>>> @end
>>>>>>
>>>>>> @implementation StringOption
>>>>>> - (NSString *)value {
>>>>>> return @"TEST";
>>>>>> }
>>>>>> @end
>>>>>>
>>>>>> int main(int argc, char *argv[]) {
>>>>>> Option *o1 = [[Option alloc] init];
>>>>>> StringOption *o2 = [[StringOption alloc] init];
>>>>>>
>>>>>> for(Option *opt in @[o1, o2]) {
>>>>>> NSLog(@"%@", [opt value]);
>>>>>> }
>>>>>>
>>>>>> if([[o2 value] hasPrefix:@"T"]) {
>>>>>> NSLog(@"That worked");
>>>>>> }
>>>>>> }
>>>>>
>>>>>
>>>>> --
>>>>> Ben
>>>>>
>>>>>
>>>>> --
>>>>> You received this message because you are subscribed to the Google Groups "Swift Language" group.
>>>>> To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
>>>>> To post to this group, send email to [hidden email].
>>>>> To view this discussion on the web visit https://groups.google.com/d/msgid/swift-language/920F0832-8164-4ADD-9BFB-EBB9B2457AB1%40tcnetworks.com.
>>>>> For more options, visit https://groups.google.com/d/optout.
>>>>
>>>
>>>
>>
>> --
>> You received this message because you are subscribed to the Google Groups "Swift Language" group.
>> To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
>> To post to this group, send email to [hidden email].
>> To view this discussion on the web visit https://groups.google.com/d/msgid/swift-language/F760AD06-AAB1-4CD9-8ECC-3B0BB58DE85B%40googlemail.com.
>> For more options, visit https://groups.google.com/d/optout.
>
>

--
You received this message because you are subscribed to the Google Groups "Swift Language" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
To post to this group, send email to [hidden email].
To view this discussion on the web visit https://groups.google.com/d/msgid/swift-language/1A8E7433-25EA-4B20-9435-5DC79C819912%40googlemail.com.
For more options, visit https://groups.google.com/d/optout.