PHP 如何为类型提示数据结构编写 phpdoc
PHP how to write a phpdoc for type hinting a data structure
我正在使用
创建新的堆栈对象
$this->postfix = new \splStack;
此堆栈将仅处理 Token
个对象
如何告诉 PHPSTORM pop 命令将返回一个 Token
对象?
我是否必须创建另一个简单地扩展 splStack 的堆栈对象,然后为其编写 phpdoc,或者我应该处理这将是困难的事实并继续前进?
谢谢,
杰森
TL;TR: 处理它。您 可以 添加一个额外的继承层,但是如果所有的好处都是让您可以拥有您想要的文档块,那真的是毫无意义的。最好使用适当的变量名 ($tokenStack
),或使用内联注释,如:/** @var Token $token */
每当您编写 $token = $tokenStack->pop();
或其他内容时。或者,看到你的堆栈显然是一个 属性,写一个方法从堆栈中弹出,然后调用它 ($this->popToken();
).
话虽这么说:如果您想要一个用于实现特定接口的对象的堆栈,那么额外的抽象层可能会有用:
class TraversableStack extends SplStack
{
public function add($index, $newVal)
{
if (!$newVal instanceof Traversable) {
throw new InvalidArgumentException('TraversableStack only accepts Traversable values');
}
return parent::add($index, $newVal);
}
/**
* @return Traversable
*/
public function pop()
{
return parent::pop();
}
}
并对所有相关方法执行相同的操作。由于 Liskov 替换原则,不允许在此处添加类型提示(子方法 必须 与父方法兼容),但是没有什么可以阻止您添加 if
's 和 throw
's 在你需要的时候。
不过,这种方法的最终结果是您的代码会(稍微)变慢,因为每个方法调用都会增加开销。所以恕我直言,我只是接受它,并使用内嵌注释来关闭 PhpStorm 关于 methods/properties 不存在。毕竟,像这样的代码并不难读:
$this->tokenStack = new \SplStack;
$this->tokenStack->push($token);
//more code
/** @var Token $lastToken */
$lastToken = $this->tokenStack->pop();
就像我在评论中所说的那样:考虑到您的堆栈已分配给 属性,您可以轻松地创建一个在内部调用 SplStack::pop
的方法,并添加您的 doc-block那里:
/**
* @return Token
* @throws \RuntimeException
*/
protected function popToken()
{
return $this->tokenStack->pop();
}
我正在使用
创建新的堆栈对象$this->postfix = new \splStack;
此堆栈将仅处理 Token
个对象
如何告诉 PHPSTORM pop 命令将返回一个 Token
对象?
我是否必须创建另一个简单地扩展 splStack 的堆栈对象,然后为其编写 phpdoc,或者我应该处理这将是困难的事实并继续前进?
谢谢, 杰森
TL;TR: 处理它。您 可以 添加一个额外的继承层,但是如果所有的好处都是让您可以拥有您想要的文档块,那真的是毫无意义的。最好使用适当的变量名 ($tokenStack
),或使用内联注释,如:/** @var Token $token */
每当您编写 $token = $tokenStack->pop();
或其他内容时。或者,看到你的堆栈显然是一个 属性,写一个方法从堆栈中弹出,然后调用它 ($this->popToken();
).
话虽这么说:如果您想要一个用于实现特定接口的对象的堆栈,那么额外的抽象层可能会有用:
class TraversableStack extends SplStack
{
public function add($index, $newVal)
{
if (!$newVal instanceof Traversable) {
throw new InvalidArgumentException('TraversableStack only accepts Traversable values');
}
return parent::add($index, $newVal);
}
/**
* @return Traversable
*/
public function pop()
{
return parent::pop();
}
}
并对所有相关方法执行相同的操作。由于 Liskov 替换原则,不允许在此处添加类型提示(子方法 必须 与父方法兼容),但是没有什么可以阻止您添加 if
's 和 throw
's 在你需要的时候。
不过,这种方法的最终结果是您的代码会(稍微)变慢,因为每个方法调用都会增加开销。所以恕我直言,我只是接受它,并使用内嵌注释来关闭 PhpStorm 关于 methods/properties 不存在。毕竟,像这样的代码并不难读:
$this->tokenStack = new \SplStack;
$this->tokenStack->push($token);
//more code
/** @var Token $lastToken */
$lastToken = $this->tokenStack->pop();
就像我在评论中所说的那样:考虑到您的堆栈已分配给 属性,您可以轻松地创建一个在内部调用 SplStack::pop
的方法,并添加您的 doc-block那里:
/**
* @return Token
* @throws \RuntimeException
*/
protected function popToken()
{
return $this->tokenStack->pop();
}