可空类型主要用于参数类型声明和函数返回值声明。

主要的两种形式如下:
<?php
function answer(): ?int  {
   return null; //ok
}
function answer(): ?int  {
   return 42; // ok
}
function say(?string $msg) {
   if ($msg) {
       echo $msg;
   }
}

从例子很容易理解,所指的就是通过 ? 的形式表明函数参数或者返回值的类型要么为指定类型,要么为 null。

此方法也可用于接口函数的定义:
<?php interface Fooable {
    function foo(?Fooable $f);
}

但有一个需要注意的地方:如果函数本身定义了参数类型并且没有默认值,即使是可空的,也不能省略,否则会触发错误。如下:
<?php function foo_nullable(?Bar $bar) {}
 
foo_nullable(new Bar); // 可行
foo_nullable(null); // 可行
foo_nullable(); // 不可行

但是如果以上函数的参数定义为 ?Bar $bar = null 的形式,则第三种写法也是可行的。因为= null 实际上相当于 ? 的超集,对于可空类型的参数,可以设定 null 为默认值。

list 的方括号简写

我们知道在 PHP5.4 之前只能通过 array() 来定义数组,5.4之后添加了 [] 的简化写法(省略了5个字符还是很实在的)。
<?php // 5.4 之前
$array = array(1, 2, 3);
$array = array("a" => 1, "b" => 2, "c" => 3);
 
// 5.4 及之后
$array = [1, 2, 3];
$array = ["a" => 1, "b" => 2, "c" => 3];

引申到另外一个问题上,如果我们要把数组的值赋值给不同的变量,可以通过 list 来实现:
<?php list($a, $b, $c) = $array;

是否也可以通过 [] 的简写来实现呢?
<?php [$a, $b, $c] = $array;

以及下一个特性中会提到的 list 指定 key:
<?php ["a" => $a, "b" => $b, "c" => $c] = $array;

PHP7.1 实现了这个特性。但是要注意的是:出现在左值中的 [] 并不是数组的简写,是list() 的简写。

但是并不仅仅如此,新的 list() 的实现并不仅仅可以出现在左值中,也能在 foreach 循环中使用:
<?php foreach ($points as ["x" => $x, "y" => $y]) {
    var_dump($x, $y);

不过因为实现的问题,list() 和 [] 不能相互嵌套使用:
<?php // 不合法
list([$a, $b], [$c, $d]) = [[1, 2], [3, 4]];
 
// 不合法
[list($a, $b), list($c, $d)] = [[1, 2], [3, 4]];
 
// 合法
[[$a, $b], [$c, $d]] = [[1, 2], [3, 4]];

允许在 list 中指定 key

上文提到过,新的 list() 的实现中可以指定key:
<?php $array = ["a" => 1, "b" => 2, "c" => 3];
["a" => $a, "b" => $b, "c" => $c] = $array;

这也就相当于:
<?php $a = $array['a'];
$b = $array['b'];
$c = $array['c'];

和以往的区别在于以往的 list() 的实现相当于 key 只能是 0, 1, 2, 3 的数字形式并且不能调整顺序。执行以下语句:
<?php list($a, $b) = [1 => '1', 2 => '2'];

会得到 PHP error: Undefined offset: 0... 的错误。

而新的实现则可以通过以下方式来调整赋值:
<?php list(1 => $a, 2 => $b) = [1 => '1', 2 => '2'];

不同于数组的是,list 并不支持混合形式的 key,以下写法会触发解析错误:
<?php // Parse error: syntax error, ...
list($unkeyed, "key" => $keyed) = $array;

更复杂的情况,list 也支持复合形式的解析:
<?php $points = [
    ["x" => 1, "y" => 2],
    ["x" => 2, "y" => 1]
];
 
list(list("x" => $x1, "y" => $y1), list("x" => $x2, "y" => $y2)) = $points;
 
$points = [
    "first" => [1, 2],
    "second" => [2, 1]
];
 
list("first" => list($x1, $y1), "second" => list($x2, $y2)) = $points;

以及循环中使用:
<?php $points = [
    ["x" => 1, "y" => 2],
    ["x" => 2, "y" => 1]
];
 
foreach ($points as list("x" => $x, "y" => $y)) {
    echo "Point at ($x, $y)", PHP_EOL;
}

void 返回类型

PHP7.0 添加了指定函数返回类型的特性,但是返回类型却不能指定为 void,7.1 的这个特性算是一个补充:
<?php function should_return_nothing(): void {
    return 1; // Fatal error: A void function must not return a value
}

以下两种情况都可以通过验证:
<?php function lacks_return(): void {
    // valid
}
 
function returns_nothing(): void {
    return; // valid
}

定义返回类型为 void 的函数不能有返回值,即使返回 null 也不行:
<?php function returns_one(): void {
    return 1; // Fatal error: A void function must not return a value
}
 
function returns_null(): void {
    return null; // Fatal error: A void function must not return a value
}

此外 void 也只适用于返回类型,并不能用于参数类型声明,或者会触发错误:
<?php function foobar(void $foo) { // Fatal error: void cannot be used as a parameter type
}

类函数中对于返回类型的声明也不能被子类覆盖,否则会触发错误:
<?php class Foo
{
    public function bar(): void {
    }
}
 
class Foobar extends Foo
{
    public function bar(): array { // Fatal error: Declaration of Foobar::bar() must be compatible with Foo::bar(): void
    }
}

类常量属性设定

这个特性说起来比较简单,就是现在类中的常量支持使用 public、private 和 protected修饰了:
<?php class Token {
    // 常量默认为 public
    const PUBLIC_CONST = 0;
 
    // 可以自定义常量的可见范围
    private const PRIVATE_CONST = 0;
    protected const PROTECTED_CONST = 0;
    public const PUBLIC_CONST_TWO = 0;
 
    // 多个常量同时声明只能有一个属性
    private const FOO = 1, BAR = 2;
}

此外,接口(interface)中的常量只能是 public 属性:
<?php interface ICache {
    public const PUBLIC = 0;
    const IMPLICIT_PUBLIC = 1;
}

为了应对变化,反射类的实现也相应的丰富了一下,增加了 getReflectionConstant 和getReflectionConstants 两个方法用于获取常量的额外属性:
<?php class testClass  {
    const TEST_CONST = 'test';
}
 
$obj = new ReflectionClass( "testClass" );
$const = $obj->getReflectionConstant( "TEST_CONST" );
$consts = $obj->getReflectionConstants();

多条件 catch

在以往的 try ... catch 语句中,每个 catch 只能设定一个条件判断:
<?php try {
    // Some code...
} catch (ExceptionType1 $e) {
    // 处理 ExceptionType1
} catch (ExceptionType2 $e) {
    // 处理 ExceptionType2
} catch (Exception $e) {
    // ...
}

新的实现中可以在一个 catch 中设置多个条件,相当于或的形式判断:
<?php try {
    // Some code...
} catch (ExceptionType1 | ExceptionType2 $e) {
    // 对于 ExceptionType1 和 ExceptionType2 的处理
} catch (Exception $e) {
    // ...
}

对于异常的处理简化了一些。

稿源:七星互联www3.qixoo.com

PHP 7.1 新特性一览的更多相关文章

  1. Java单元測试工具JUnit 5新特性一览

    Java单元測试工具JUnit 5新特性一览 作者:chszs,未经博主同意不得转载. 经许可的转载需注明作者和博客主页:http://blog.csdn.net/chszs JUnit是最流行的开源 ...

  2. IntelliJ IDEA 16 EAP新特性一览

    IntelliJ IDEA 16 EAP新特性一览 作者:chszs,未经博主同意不得转载.经许可的转载需注明作者和博客主页:http://blog.csdn.net/chszs IntelliJ I ...

  3. (数据科学学习手札111)geopandas 0.9.0重要新特性一览

    本文示例文件已上传至我的Github仓库https://github.com/CNFeffery/DataScienceStudyNotes 1 简介 就在几天前,geopandas释放了其最新正式版 ...

  4. (数据科学学习手札129)geopandas 0.10版本重要新特性一览

    本文示例代码及文件已上传至我的Github仓库https://github.com/CNFeffery/DataScienceStudyNotes 1 简介 就在前不久,我们非常熟悉的Python地理 ...

  5. (数据科学学习手札139)geopandas 0.11版本重要新特性一览

    本文示例代码已上传至我的Github仓库https://github.com/CNFeffery/DataScienceStudyNotes 1 简介 大家好我是费老师,就在几天前,geopandas ...

  6. Spring Boot 2.3.0正式发布:优雅停机、配置文件位置通配符新特性一览

    当大潮退去,才知道谁在裸泳..关注公众号[BAT的乌托邦]开启专栏式学习,拒绝浅尝辄止.本文 https://www.yourbatman.cn 已收录,里面一并有Spring技术栈.MyBatis. ...

  7. Spring 4支持的Java 8新特性一览

    有众多新特性和函数库的Java 8发布之后,Spring 4.x已经支持其中的大部分.有些Java 8的新特性对Spring无影响,可以直接使用,但另有些新特性需要Spring的支持.本文将带您浏览S ...

  8. HTML5和CSS3新特性一览

    HTML5 1.HTML5 新元素 HTML5提供了新的元素来创建更好的页面结构: 标签 描述 <article> 定义页面独立的内容区域. <aside> 定义页面的侧边栏内 ...

  9. JDK8新特性一览

    转载自:http://blog.csdn.net/qiubabin/article/details/70256683 官方新特性说明地址 Jdk8新特性.png 下面对几个常用的特性做下重点说明. 一 ...

  10. Oracle 18c新特性一览

    1. 一般新特性 1.1. Shadow Lost Write Protection Shadow lost write protection检测到一个丢失的写,它会导致一个主要的数据损坏.可以在不需 ...

随机推荐

  1. U3D Debug.log的问题

    今天在测试有yield有关的问题时,发现Debug.log()是异步输出机制.不一定会在调用后立即执行. 在C++有类似问题:std::cout 也不一定会立即输出,加上"\n"或 ...

  2. Caffe学习系列(19): 绘制loss和accuracy曲线

    如同前几篇的可视化,这里采用的也是jupyter notebook来进行曲线绘制. // In [1]: #加载必要的库 import numpy as np import matplotlib.py ...

  3. 发布HTML5 RTS游戏-古代战争

    古代战争 游戏介绍 "古代战争"是一个2.5D即时战略游戏,使用了帝国时代2的素材,并参考了它的游戏设计和玩法. 游戏基于YEngine2D引擎开发,具备生产.建造.资源采集.战斗 ...

  4. Quartz.NET syudy

    Quartz.NET   Quartz.NET是一个开源的作业调度框架,是OpenSymphony 的 Quartz API的.NET移植,它用C#写成,可用于winform和asp.net应用中.它 ...

  5. Android四大布局及其主要属性

    布局: <LinearLayout></LinearLayout> <RelativeLayout></RelativeLayout> <Fram ...

  6. 【MPI0】学习资料搜集

    一个不错的英文的MPI教程:http://mpitutorial.com 中科大的MPI学习资料:http://micro.ustc.edu.cn/Linux/MPI/ 清华大学的并行计算资料:htt ...

  7. 每个Android开发者都应该了解的资源列表

    前言   这是一篇译文,原文地址Resources every Android developer must know,在译文开头,推荐两篇同样适合于Android开发者阅读的资源列表Android开 ...

  8. 云计算之路-阿里云上:Wireshark抓包分析一个耗时20秒的请求

    这篇博文分享的是我们针对一个耗时20秒的请求,用Wireshark进行抓包分析的过程. 请求的流程是这样的:客户端浏览器 -> SLB(负载均衡) -> ECS(云服务器) -> S ...

  9. VC6.0读取Excel文件数据

    啰嗦一下:本人所在公司从事碟式斯特林太阳能发电设备的研发与销售.单台设备图如下: 工作原理如下:整个设备大致可分为五个部分, 1.服务器,负责气象.发电等数据存取,电.网连接等处理: 2.气象站,通过 ...

  10. VMware v12.1.1 专业版以及永久密钥

    热门虚拟机软件VMware Workstation 现已更新至v12.1.1 专业版!12.0属于大型更新,专门为Win10的安装和使用做了优化,支持DX10.4K高分辨率显示屏.OpenGL 3.3 ...