Na navigaci | Klávesové zkratky

Should nullable types be written with or without a question mark?

I've always been bothered by any redundancy or duplication in code. I wrote about it many years ago. Looking at this code just makes me suffer:

interface ContainerAwareInterface
{
    /**
     * Sets the container.
     */
    public function setContainer(ContainerInterface $container = null);
}

Let's set aside the unnecessary commentary on the method for now. And this time also the misunderstanding of dependency injection, if a library needs such an interface. The fact that using the word Interface in the name of an interface is, in turn, a sign of not understanding object-oriented programming, I'm planning a separate article on that. After all, I've been there myself.

But why on earth specify the visibility as public? It's a pleonasm. If it wasn't public, then it wouldn't be an interface, right? And then someone thought to make it a “standard” ?‍♂️

Sorry for the long introduction, what I'm getting to is whether to write optional nullable types with or without a question mark. So:

// without
function setContainer(ContainerInterface $container = null);
// with
function setContainer(?ContainerInterface $container = null);

Personally, I have always leaned towards the first option, because the information given by the question mark is redundant (yes, both notations mean the same from the language's perspective). This is how all the code was written until the arrival of PHP 7.1, the version that added the question mark, and there would have to be a good reason to change it suddenly.

With the arrival of PHP 8.0, I changed my mind and I'll explain why. The question mark is not optional in the case of properties. PHP will throw an error in this case:

class Foo
{
	private Bar $foo = null;
}
// Fatal error: Default value for property of type Bar may not be null.
// Use the nullable type ?Bar to allow null default value

And from PHP 8.0 you can use promoted properties, which allows you to write code like this:

class Foo
{
	public function __construct(
		private ?Bar $foo = null,
		string $name = null,
	) {
		// ...
	}
}

Here you can see the inconsistency. If ?Bar is used (which is necessary), then ?string should follow on the next line. And if I use the question mark in some cases, I should use it in all cases.

The question remains whether it is better to use a union type string|null instead of a question mark. For example, if I wanted to write Stringable|string|null, maybe the version with a question mark isn't at all necessary.

Update: It looks like PHP 8.4 will require the notation with a question mark.

You might be interested in

Leave a comment

Text of the comment
Contact

(kvůli gravataru)



*kurzíva* **tučné** "odkaz":http://example.com /--php phpkod(); \--

phpFashion © 2004, 2024 David Grudl | o blogu

Ukázky zdrojových kódů smíte používat s uvedením autora a URL tohoto webu bez dalších omezení.