【问题标题】:php method argument type hinting with question mark (?type)php 方法参数类型提示带问号 (?type)
【发布时间】:2018-07-30 14:13:22
【问题描述】:

我只是觉得在方法类型提示中使用问号的 php (symfony/laravel) 代码片段:

public function functionName(?int $arg = 0)

在其他情况下,?type 不是最后一个,但我还没有找到没有默认值的这些。

问题是,我找不到有关此的任何信息,我检查了:

和7.2一样,但是由于代码只需要7.1,所以看起来比较正常。

我也用谷歌搜索过,并在这里搜索过,但要么没有记录,要么问号主题击败了搜索引擎。

所以我现在觉得有点笨,如果有人能告诉我这个问号在方法签名参数中的重要性,我将不胜感激。

谢谢

【问题讨论】:

标签: php


【解决方案1】:

这是php7.1中的一个新特性

http://php.net/manual/en/migration71.new-features.php

问号表示类型提示参数(或返回值)也允许为空。

所以在你的例子中 $arg 可以是 null 或任何整数。

【讨论】:

    【解决方案2】:

    只是添加到先前答案的注释 - 它必须是 null 或具有指定类型的值,即 - 你不能只是省略它 - 看看一个例子:

    class TestClass {
    
        public function fetch(?array $extensions)
        {
            //...
        }        
    }
    

    现在如果你打电话

    (new TestClass)->fetch();
    

    这会抛出

    ArgumentCountError : 函数 fetch() 的参数太少 ...

    要使其在不传递 $extensions 数组的情况下工作,您必须使用 null 作为参数调用它

    (new TestClass)->fetch(null);
    

    它在您将最初设置为 null 的参数传递给另一个处理方法的情况下效果最好,即

    class TestClass {
    
        public function fetch(array $extensions = null)
        {
            //...
    
            $this->filter($extensions);
        }
    
        private function filter(?array $extensions)
        {
            //...
        }
    }
    

    现在你可以在没有参数的情况下调用fetch 方法

    (new TestClass)->fetch();
    

    【讨论】:

    • 没错,它是完美的,没有默认值,你只能用问号将参数显式设置为null,如果有一个,你可以完全省略它。跨度>
    • 拥有private function filter(?array $extensions)和private function filter(array $extensions = null)有什么区别
    • @Quiquetas (?array $p) $p 必须是一个数组或 null,无论如何它必须在调用时提供。 (?array $p=null) 同理,$p 必须是数组或 null,但默认值为 null,本次调用时可以省略该参数。关于public function fetch(array $extensions = null) sn-p,好吧,ti 只是一个潜在的错误,因为 $extensions 不能为空。但只有在不带参数的情况下调用 fetch 时才会触发,例如 $obj->fetch();。原因写在上面。
    【解决方案3】:

    考虑以下函数:

    <?php
    
    function testFnc1(string $param)
    {
        var_dump($param);
    }
    
    function testFnc2(string $param = 'some string')
    {
        var_dump($param);
    }
        
    function testFnc3(string $param = null)
    {
        var_dump($param);
    }
    
    function testFnc4(?string $param)
    {
        var_dump($param);
    }
    
    function testFnc5(?string $param = 'some string')
    {
        var_dump($param);
    }
    
    
    function testFnc6(?string $param = null)
    {
        var_dump($param);
    }
    

    现在我们测试不同值的函数。

    fnc no argument null '' 'other string'
    1 FATAL ERROR Uncaught ArgumentCountError FATAL ERROR Uncaught TypeError: Argument 1 passed to testFnc1() must be of the type string, null given string(0) "" string(12) "other string"
    2 string(11) "some string" FATAL ERROR Uncaught TypeError: Argument 1 passed to testFnc2() must be of the type string, null given string(0) "" string(12) "other string"
    3 NULL NULL string(0) "" string(12) "other string"
    4 FATAL ERROR Uncaught ArgumentCountError NULL string(0) "" string(12) "other string"
    5 string(11) "some string" NULL string(0) "" string(12) "other string"
    6 NULL NULL string(0) "" string(12) "other string"

    注意testFnc3(string $param = null) 和testFnc4(?string $param) 在以下情况下的区别:

    1. 没有传递任何参数
    2. 参数是null

    您可以调用testFnc3(),但不能调用testFnc4(),因为它没有声明默认值。

    您必须致电testFnc4(null)。

    所以testFnc4(?string $param) 允许$param 成为null,但必须提供这样的参数。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-07-11
      • 2019-12-09
      • 2018-01-20
      • 2017-01-03
      • 2013-01-13
      • 2021-11-16
      • 2019-02-08
      相关资源
      最近更新 更多