这已经被一遍又一遍地问了一遍又一遍,但是这些回复有点过时了,我有些绝望地希望一些改变,因为“不能做”的回复。
上下文:
class AbstractBuildObject {}
class Hammer extends AbstractBuildObject{}
class Nail extends AbstractBuildObject{}
class AbstractFactory{
/**
* return $type
*/
public function build1(string $type): AbstractBuiltObject {
return new $type();
}
/**
* return any(AbstractBuiltObject)
*/
public function build2(string $someArg): AbstractBuiltObject {
$type = $this->decideTypeBasedOnArgsAndState($someArg);
return new $type();
}
}我试图用上面的注释来表示我需要的东西。
return $type (或者理想情况下,return $type of AbstractBuiltObject应该暗示返回类型是在输入参数中指定的。
在第二种情况下,any(AbstractBuiltObject)表示可以返回抽象类的任何派生的具体化。
因此,我需要某种注释来实现我所描述的效果。这些注释显然不起作用,我只是用它们来说明这个概念。
我知道人们可能会尝试使用管道类型连接(如return Hammer|Nail ),但在我的示例中,每次向项目添加新的具体实现时,工厂类都应该保持修改,在build1情况下,它也不够具体,因为我确切地知道返回类型应该是什么。
因此,简而言之,我需要至少在PhpStorm中这样做:
(new AbstractFactory())->build1(Hammer::class)-> // I should have Hammer autocomplete here
(new AbstractFactory())->build2('foo')-> // I should have autocomplete of any concretion of the abstract here发布于 2021-03-07 14:56:11
我们采用的解决办法是:
<?php
class AbstractBuiltClass {
/**
* @return static
*/
public static function type(self $instance)
// change return type to :static when #PHP72 support is dropped and remove explicit typecheck
:self
{
if(!($instance instanceof static)){
throw new Exception();
}
return $instance;
}
}
class Hammer extends AbstractBuiltClass{
function hammerMethod(){}
}
Hammer::type($factory->get(Hammer::class))->hammerMethod();寻求可行解决办法的竞争者:
发布于 2021-03-04 16:30:10
关于打破D的哲学对话,如果你想要像这样的东西自动完成那些只在Hammer上可用的方法
(new AbstractFactory())->build1(Hammer::class)->然后,您已经承诺专门为Hammer类编写这段代码。如果你要这么做,那你也可以这样做:
$hammer = (new AbstractFactory())->build1(Hammer::class);如果你这样做,你也可以这样做:
/**
* @var Hammer
*/
$hammer = (new AbstractFactory())->build1(Hammer::class);然后,您在$hammer->上的自动完成应该可以工作。
https://stackoverflow.com/questions/66478401
复制相似问题