最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

php - What's the difference between a type and a type declaration? - Stack Overflow

programmeradmin2浏览0评论

PHP singleton type documentation says little about the false type and true type (both are also considered singleton types).

Could anybody please explain why does:

function myFunction(): false
{
    return 1 < 0;
}

$result = myFunction();
var_dump($result);

Return bool(false) and not something like false(false) or singleton(false)?

This is quite frustrating because since the documentation doesn't specify whether false type and true type are return-only types or value types, I expected them to be value types, meaning creating a variable of this type should be valid, which turns out not to be the case.

PHP singleton type documentation says little about the false type and true type (both are also considered singleton types).

Could anybody please explain why does:

function myFunction(): false
{
    return 1 < 0;
}

$result = myFunction();
var_dump($result);

Return bool(false) and not something like false(false) or singleton(false)?

This is quite frustrating because since the documentation doesn't specify whether false type and true type are return-only types or value types, I expected them to be value types, meaning creating a variable of this type should be valid, which turns out not to be the case.

Share Improve this question edited Feb 15 at 14:50 rozsazoltan 8,2755 gold badges18 silver badges38 bronze badges asked Feb 15 at 12:08 RedgardRedgard 396 bronze badges 5
  • 1 I suppose it's a documentation problem and you can just submit a pull request calling them not types but return type declarations – Your Common Sense Commented Feb 15 at 12:17
  • 1 @YourCommonSense They can be used in any type constraint, not just return types - see for instance this demo of a property that allows false but rejects true: 3v4l./WWcEk – IMSoP Commented Feb 15 at 13:07
  • So it's just a type declaration, without retur. the rest is same. Submit a pull request, problem solved – Your Common Sense Commented Feb 15 at 13:57
  • 1 @YourCommonSense A "type declaration" is just a place where you can use types; the types themselves still exist as part of a comprehensive type system. The manual could definitely be expanded on where_/_how and why certain types can be used, but what's written there is perfectly accurate: PHP has support for using true and false as types, and considers them sub-types of the type bool. Compare OO types: any instance of a particular interface will also be an instance of some concrete class, but we can still accurately call the interface a type. – IMSoP Commented Feb 15 at 14:44
  • There are variable types and type declarations. They don't exactly match. End of story. – Your Common Sense Commented Feb 15 at 16:08
Add a comment  | 

2 Answers 2

Reset to default 3

The first thing to clarify here is that types in declarations are primarily assertions: when you say function foo(): SomeType you are telling PHP to throw an error if the function tries to return anything other than SomeType. There are cases where PHP will coerce the result type, and only throw an error if the coercion fails, such as turning the integer 1 into the float 1.0; but if the value returned is already an acceptable type, it will be left alone.

The second thing to clarify is that the syntax for specifying what types are accepted is richer than the set of types which a value can hold. For instance, it includes "union types" like string|int which means "any string or any integer"; you can't have a value of type string|int, but you can look at a value and see if it matches that constraint.

Putting these together, the role of true and false in type declarations becomes clearer: they are not describing new types in the language, they are just questions you can ask about a variable. The original motivation was to document the calling convention of existing functions such as strpos "returns the location as an integer on success, boolean false on failure". You could mark that as returning int|bool, but since it never returns true, specifying int|false is more precise. That doesn't mean false is a new type, it just means that if the function tried to return true, the engine could throw an error that "true does not meet the constraint int|false".

The ability to specify true in the same place was actually added later, to make things more complete and consistent. The labelling of these as "singleton types" is just a theoretical description of how different types relate to each other - false is a sub-type of bool in the same way that DateTimeImmutable is a sub-type of DateTimeInterface. Note that these "singleton types" are not constrained to use only in return types, they can for instance be used in the type of a property with exactly the same meaning.

<?php declare(strict_types=1);

class Foo {
   public int|false $bar;
}

$foo = new Foo;
$foo->bar = 42; // OK
$foo->bar = false; // OK
$foo->bar = true; // TypeError: Cannot assign true to property Foo::$bar of type int|false

At first glance, it might seem pointless to specify true or false outside a union type, but it might be useful with polymorphism: if an interface says that a method must return int|false, it is allowed for an implementation to say it only ever returns int, or that it only ever returns false. Similarly, an interface might specify a return type of bool, but an implementation wants to document that it only ever returns true - a valid boolean, but a more specific constraint.

It can only return the false value, but the value itself still belongs to the bool type.

Singleton types are those which allow only one value.

  • Singleton types

So the false singleton type only accepts the result bool(false), while for the true singleton type, the expected return value will only be bool(true). This is especially useful when we want to tighten a inherited function that already returns a bool result.

发布评论

评论列表(0)

  1. 暂无评论