我们有实现__toString()
的对象:
class Foo {
public function __toString()
{
return 'bar';
}
}
然后我们有返回
string
或实现__toString()
的对象的函数,如上面的示例。当对字符串使用返回类型
string
时,当然可以:function getString():string {
return 'Works!';
}
返回
Foo
类型的对象不起作用,因为它不是string
:function getString(Foo $foo):string {
return $foo; // Fatal TypeError!
}
是否有任何php接口可用于键入hint
string
和实现该未知接口的对象,例如Printable
或Stringable
(lol)?目标是能够返回
string
或实现特定接口的对象(这将强制实现__toString
)。 最佳答案
简单的回答是“否”-没有内置的“stringable”提示,也不支持任意的“union类型”(其中string|Stringable
表示“astring
或instanceof Stringable
”)。
部分原因,以及你需要问的设计问题,是你在这里实际代表的是什么合同?从调用代码的角度来看,不能保证返回值实际上可以直接用作字符串-有许多操作对字符串和对象的行为不同,或者接受字符串但不自动转换对象。因此,这样的提示实际上唯一能保证的是(string)$foo
将给出一个字符串。
所以你有几个选择:
作为Stefan says,总是返回一个对象,实现一些接口Stringable
。如果函数想要返回一个字符串,它首先将其包装在一个简单的对象中。
不要使用泛型的Stringable
,而要返回一个更有意义的接口;例如,可能您实际返回的是一些Loggable
。这样,包装字符串可以给您带来更具体的好处:您可以向接口添加其他方法,调用代码在调用这些方法之前不需要执行“对象或字符串”检查。
如果调用代码只将返回值用作字符串,则根本不返回对象。将函数标记为returningstring
,并在返回对象之前将任何对象强制转换为字符串。
如果希望调用代码检查返回值并对不同类型的对象执行不同的操作,则完全不要限制返回类型。无论如何,您并没有真正将返回类型视为一个契约。