1. 程式人生 > 其它 >Java8 中使用Stream 讓List 轉 Map使用總結

Java8 中使用Stream 讓List 轉 Map使用總結

本篇文章主要是介紹php7相對於php5.6的一些新的特性。

目錄

增加箭頭函式的支援

  • 主要是為了提高程式碼的可讀性和簡潔性
  • 語法:fn($n) => $n * $n * $n

如下所示:


$a = [1, 2, 3, 4, 5];

$b = array_map(fn($n) => $n * $n * $n, $a);

print_r($b);


預載入

  • 主要目的是提升 PHP 7.4 的效能
  • 預載入是在OPcache中載入檔案、框架和庫的過程,絕對是新版本的最佳補充

弱引用

  • php7.4中增加的
  • 弱引用也是一種引用形式,如果我們銷燬了原來的物件,那麼弱引用物件也會被銷燬
  • 有利於垃圾回收
  • 語法:WeakReference::create($obj)

原來的賦值方式的物件引用,在unset原來的物件之後,記憶體中的實際物件沒有被釋放,只是切斷了關聯:

$obj = new stdClass;
$weakRef = $obj;

var_dump($weakRef);
// object(stdClass)#1 (0) {
// }

unset($obj);
var_dump($weakRef);
// object(stdClass)#1 (0) {
// }

通過弱引用的方式,在unset原始物件之後,記憶體中的實際物件也會被釋放:

$obj = new stdClass;
$weakRef = WeakReference::create($obj);

var_dump($weakRef->get());
// object(stdClass)#2 (0) {
// }

unset($obj);
var_dump($weakRef->get());
// NULL

直接使用 new 來建立物件,這種形式是不行的,會一直返回 NULL 。因為弱引用是通過變數來建立的,它指向的是原始物件的符號表,而變數和物件之間的符號表連線才是弱引用關心的內容,它會根據符號表的狀態來判斷當前的狀態:

$weakRef = WeakReference::create(new stdClass);
var_dump($weakRef->get());
// NULL

空合併操作符

  • 可以減少書寫程式碼的邏輯
  • 語法:??
$name = $name ?? "NoName";  // 如果$name有值就取其值,否則設$name成"NoName"

陣列表示式中的展開運算子

  • 展開運算子被認為是一種語言結構,而 array_merge 是一個函式
  • 針對常量陣列的編譯時長優化,效能將會提升
  • 語法:[...$parts]
$parts = ['apple', 'pear'];
$fruits = ['banana', 'orange', ...$parts, 'watermelon'];
print_r($fruits);
// Array ( [0] => banana [1] => orange [2] => apple [3] => pear [4] => watermelon )

新增型別提示

  • php5.0增加的函式引數物件型別提示:function printPerson(Person $personObject){}
  • php5.1增加的函式引數的陣列型別提示:function printSkill(array $arr) {}
  • php7增加的標量型別提示:function printRecord(string $name, int $id, float $salary, bool $sex){}

函式和方法返回的型別提示

  • 規定返回值必須是指定的型別:function getRecord(string $name) : string {}
  • PHP 7.1 引入了 Void 返回型別

程式碼示例:

function first(): void {
    // ...
}

function second(): void {
    // ...
    return;
}

嚴格型別約束

  • 檔案的第一條語句的位置放上檔案級別指令declare(strict_types=1)來宣告的這個檔案

如果沒有規定嚴格型別限制的話,那麼對於標量型別的引數型別提示和返回值型別提示將不影響程式的執行:

// 1、宣告函式
function getPrice(int $price) : int {
    return $price;
}

// 2、執行函式,程式會將10.2轉為整型,直接捨棄小數點,這可能會導致問題
getPrice(10.2);

但是,需要注意的是,物件及陣列型別還是具備約束力。

生成器特性

  • 新增的生成器委託
  • 生成器委託的形式為:yield from <expr><expr>的結果得是可遍歷物件或陣列。

程式碼示例:

$generator = function () {
	// 會先迭代這個部分內容
	yield from range(1, 3);
	
	// 然後再執行這部分內容
	foreach (range(4, 6) as $i) {
		yield $i;
	}
};

// 將輸出1、2、3、4、5、6
foreach ($generator() as $value) {
	echo "$value";
}
  • 生成器返回表示式

程式碼示例:

$traverser = (function () {
  yield "foo";
  yield "bar";
  return "value";
})();

// 這裡將不會輸出,因為沒有迭代的話,將不會執行
$traverser->getReturn();

foreach ($traverser as $value) {
    echo "{$value}", PHP_EOL;
}

$traverser->getReturn();  // "value"

飛船操作符

  • 形式:(expr) <=> (expr)
  • 左邊運算物件小,則返回-1;左、右兩邊運算物件相等,則返回0;左邊運算物件大,則返回1

程式碼示例:

$name = ["Simen", "Suzy", "Cook", "Stella"];
usort($name, function ($left, $right) {
    return $left <=> $right;
});
print_r($name);

常量陣列

  • PHP 7 之前只允許類/介面中使用常量陣列,現在 PHP 7 也支援非類/介面的普通常量陣列了

程式碼示例:

define("USER", [
  "name"  => "Simen",
  "sex"   => "Male",
  "age"   => "38",
  "skill" => ["PHP", "MySQL", "C"]
]);
// USER["skill"][2] = "C/C++";  // PHP Fatal error:  Cannot use temporary expression in write context in...

統一了變數語法

  • 統一了由左向右結合的規則
$goo = [
    "bar" => [
        "baz" => 100,
        "cug" => 900
    ]
];

$foo = "goo";

// 實際為:($$foo)['bar']['baz']; PHP 5 中為:${$foo['bar']['baz']};
// PHP 7 中一個籠統的判定規則是,由左向右結合。
$$foo["bar"]["baz"];
                      

新增的Throwable 介面

  • \Exception\Error 類都實現了 Throwable,所以這個可以捕獲這些異常
  • 好像記憶體超出的異常不能被捕獲到
try {
    $name = $name->method();
} catch (\Throwable $e) {
    echo  $e->getMessage();
}

補充:好像實際開發過程中,類似記憶體超時這種錯誤,仍舊無法捕獲到!

新增use 組合宣告

  • use 組合宣告可以減少 use 的輸入冗餘

程式碼示例:

use PHPGoodTaste\Utils\{
    Util,
    Form,
    Form\Validation,
    Form\Binding
};

一次捕捉多種型別的異常、錯誤

  • PHP 7.1 新添加了捕獲多種異常/錯誤型別的語法——通過豎槓|來實現。

程式碼示例:

try {
      throw new LengthException("LengthException");
    //   throw new DivisionByZeroError("DivisionByZeroError");
    //   throw new Exception("Exception");
} catch (\DivisionByZeroError | \LengthException $e) {
    echo "出錯訊息 --- ", $e->getMessage(), PHP_EOL;
} catch (\Exception $e) {
    echo "出錯訊息 --- ", $e->getMessage(), PHP_EOL;
} finally {
    // ...
}

常量可見性修飾符

  • PHP 7.1類常量可以可見性修飾符的

程式碼示例:

class YourClass 
{
    const THE_OLD_STYLE_CONST = "One";

    public const THE_PUBLIC_CONST = "Two";
    private const THE_PRIVATE_CONST = "Three";
    protected const THE_PROTECTED_CONST = "Four";
}

iterable 偽型別

  • PHP 7.1 引入了 iterable 偽型別
  • iterable 型別適用於陣列、生成器以及實現了 Traversable 的物件,它是 PHP 中保留類名。

程式碼示例:

$fn = function (iterable $it) : iterable {
    $result = [];
    foreach ($it as $value) {
        $result[] = $value + 1000;
    }
    return $result;
};

$fn([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);

可空型別

  • PHP 7.1 引入了可空型別。
  • 對於同一型別的強制要求,可以設定其是否可空。

程式碼示例:

$fn = function (?int $in) {
    return $in ?? "NULL";
};

$fn(null);
$fn(5);
$fn();  // TypeError: Too few arguments to function {closure}(), 0 passed in ...