Re: [RFC][Discussion] Return Type Variance Checking
| From: | Marc Bennewitz | Date: | Tue, 25 Nov 2014 22:19:32 +0000 |
| Subject: | Re: [RFC][Discussion] Return Type Variance Checking | ||
| References: | 1 2 3 4 | Groups: | php.internals |
| Request: | Send a blank email to internals+get-79183@lists.php.net to get a copy of this message | ||
Am 25.11.2014 um 23:13 schrieb Marc Bennewitz:
Am 25.11.2014 um 22:43 schrieb Levi Morrison:@see http://3v4l.org/UhtObOn Tue, Nov 25, 2014 at 2:07 PM, Marc Bennewitz <dev@mabe.berlin> wrote:Yes it does - thank you for explanation - my mistake :/ Option 3 is a no go not from OOP perspective and from consistency pov as we already allow this in type-hint: class FooFactory {I think it's required to do the type check on runtime (Option 2) because one of the use cases for return type-hint are factories and such often do instantiation in base of unknown string values: class MyFactory {It seems that I did not explain this clearly enough; I apologize. The variance has to do with the declared type in the function signature when inheritance is involved, not the type of the value returned by the function. For instance, under any of the three options this code will work just fine: class Foo {} class Goo extends Foo {} class FooFactory {public static function factory($name) : AdapterInterface { $class = 'MyNamespace\Adapter\' . $name; return $class(); }}function create(): Foo { return new Goo(); }} As long as the return value from FooFactory::create returns Foo or a subtype of Foo (such as Goo), then it will work. The variance that is under discussion in this thread is about the declared return type in the signature: class GooFactory extends FooFactory {function create(): Goo {}} In this case, GooFactory::create() declares a return type of Goo, which is a subtype of Foo [the return type of the inherited method FooFactory::create()]. This is a covariant return type. If we choose option 3, the only possible return type for GooFactory::create is Foo. Hopefully this clarifies the issue.function create(Foo $foo): Foo { return $foo; }} class GooFactory extends FooFactory {function create(Goo $goo): Goo { return $goo; }} OK HHVM allows it - we also allow it but trigger an E_STRICT error