hack泛型:約束條件

2018-11-10 16:10 更新

hack泛型類型約束條件表示為了被接受為給定類型參數(shù)的類型參數(shù),類型必須滿足的要求。(例如,它可能必須是給定的類類型或該類類型的子類型,或者可能必須實現(xiàn)給定的接口。

hack泛型類型約束有兩種,分別由關(guān)鍵字as和super關(guān)鍵字指定。每個都在下面討論。

通過as指定約束

考慮下面的例子,其中類Complex有一個類型參數(shù)T,并且有一個約束num:

<?hh

namespace Hack\UserDocumentation\Generics\Constraints\Examples\Constraint;


class Complex<T as num> {
  private T $real;
  private T $imag;
  public function __construct(T $real, T $imag) {
    $this->real = $real;
    $this->imag = $imag;
  }
  public static function add(Complex<T> $z1, Complex<T> $z2): Complex<num> {
    return new Complex($z1->real + $z2->real, $z1->imag + $z2->imag);
  }

  public function __toString(): string {
    if ($this->imag === 0.0) {
      // Make sure to cast the floating-point numbers to a string.
      return (string) $this->real;
    } else if ($this->real === 0.0) {
      return (string) $this->imag . 'i';
    } else {
      return (string) $this->real . ' + ' . (string) $this->imag . 'i';
    }
  }
}

function run(): void {
  $c1 = new Complex(10.5, 5.67);
  $c2 = new Complex(4, 5);
  // You can add one complex that takes a float and one that takes an int.
  echo "\$c1 + \$c2 = " . Complex::add($c1, $c2) . "\n";
  $c3 = new Complex(5, 6);
  $c4 = new Complex(9, 11);
  echo "\$c3 + \$c4 = " . Complex::add($c3, $c4) . "\n";
}

run();

Output

$c1 + $c2 = 14.5 + 10.67i
$c3 + $c4 = 14 + 17i

沒有這個as num約束,會報告一些錯誤,包括以下內(nèi)容:

  • return方法中的語句add對未知類型的值執(zhí)行算術(shù)運算T,但是對于所有可能的類型參數(shù)沒有定義算術(shù)。
  • if方法中的語句__toString將未知類型的值T與a float進行比較,但是沒有為所有可能的類型參數(shù)定義這樣的比較。
  • return方法中的語句會__toString取消未知類型的值T,但是對于所有可能的類型參數(shù)都沒有定義這樣的操作。同樣,一個未知類型的值T正在與一個字符串連接。

該run()代碼創(chuàng)建float并int分別情況下,類的Complex。

總之,T as U斷言T必須是一個子類型U。

通過。指定約束 super

與as類型約束不同,T super U斷言T必須是超類型的U。

這種約束相當奇特,但解決了多種類型“碰撞”時遇到的一個有趣的問題。下面是一個如何concat在庫接口類型中使用方法的例子ConstVector

interface ConstVector<+T> {
  public function concat<Tu super T>(ConstVector<Tu> $x): ConstVector<Tu>;
  // ...
}

考慮我們調(diào)用concatVector<float>和a 連接的情況Vector<int>。由于它們有一個共同的超類型,num所以這個super約束允許檢查器確定這num是推斷的類型Tu。


以上內(nèi)容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號