如果理解了運算子的優先順序與結合性,那麼管道運算子的執行機制也變得容易理解了,本節對此進行介紹。
在f#中,運算子存在優先順序與結合性,這兩者是運用運算子進行表示式的計算時,是按什麼順序依次執行表示式各部分的計算的決定因素。
基本上是先執行優先順序高的運算部分,優先順序相等時按結合性決定運算順序。結合性分為兩種,從右往左進行的計算稱為右結合,從左往右的計算稱為左結合。大部分的運算子(特別是函式運用)都是左結合,同時,表示式被()括起來的時候,先執行()中的運算。
首先,舉個優先順序不同的例子。因為加法運算的優先順序比乘法運算的優先順序低,所以以下表示式的執行結果相同。
結合的強度
1 2 * 3 4 * 5 6;;1 (2 * 3) (4 * 5) 6;;
同時,結合的強度相等時由結合性決定運算順序。在下例中,可以確認**(冪)是右結合的。
結合性
> 2.0 ** 3.0 ** 2.0;;val it : float = 512.0
> 2.0 ** (3.0 ** 2.0);;
val it : float = 512.0
> (2.0 ** 3.0) ** 2.0;;
val it : float = 64.0
要理解函式呼叫的順序,必須要記住「f#的函式全部為單引數函式」。
函式呼叫
let h x = x * 2;;let f x y z = x y z;;
//以下三個為相同意思
f 1 2 3;;
(f 1) 2 3;;
((f 1) 2) 3;;
//錯誤,執行了(f 1) ((2 3) 4)
f 1 2 3 4;; //與函式(f 1)的加法運算尚未定義
h 1 2;; //(h 1) 2。不是h (1 2)
h(1 2);;
1 h 2;; // 1 (h 2)
2 3;; //錯誤。這樣不被看作是函式呼叫。
全部函式為單引數時,連續呼叫函式時就有點不方便。
譬如下面這個例子。
想要進行函式合成
> let f x = x 1;;val f : int -> int
> let g x = x * 2;;
val g : int -> int
> f g 3;; //錯誤
> f (g 3);; //這樣是正確的
//譬如這樣寫就很不方便
> f (g (h (i (j (k x)))))
這種情況下,可以使用管道運算子。
使用管道運算子的例子
let f x = x 1;;let g x = x * 2;;
let h x y = x y;;
3 |> g |> f |> f |> f;; //計算 (f (f (f (g 3))))
f <| f <| f <| g 3;; //這樣是錯誤的
h <| f 2 <| g 3;; //但是這樣是正確的
另外,在允許不帶引數的語言中(基本上所有的語言都是這樣的),有可以書寫象f g 3這種寫法的語言。例如perl中
與其他語言的比較
//f#let print x = printfn "%d" x in
print 1 2 * 3;; //這樣是錯誤的 執行了(print 1) 2*3
#perl
#!/usr/bin/perl
print 1 2 * 3; #ok
雖然這樣寫比較清晰,因而受人歡迎,但是使用柯里化處理起來也很方便。
第三章 第五節
pop ax 指令的執行過程 1 將ss sp指向的記憶體單元處的資料送入ax中。2 sp sp 2,ss sp指向當前棧頂下面的單元,以當前棧頂下面的單元為新的棧頂。注意 1 出棧後,ss sp指向新的棧頂,1000eh,pop操作前的棧頂元素,1000ch處的2266h依然存在,但是,它已經不在...
第三章 第五節 集合
集合是乙個無需不重複的序列,用set來表示 零 建立集合 建立集合的方式有兩種,分別是 和set 下面我們來具體講解一下。形式 形式用來建立乙個非空集合,語法如下 set 下面我們通過例子來看一下具體怎麼使用 例子 一 定義乙個包含字串的集合 name 例子 二 定義乙個包含多種型別的集合 pers...
第三章第五節 相似 仿射 射影變換
引言 除了歐式變換,空間中還有其他的變換,只不過歐式變換是最簡單的變換,他不改變物體的形狀,而其他的變換則會改變物體的外形。和歐式變換相似,其他變換均有類似的矩陣表示。變換性質 相似變換在歐式變換的基礎上多了乙個自由度,為7自由度,允許物體進行均勻縮放。相似變換矩陣tsts t s srt 0t1 ...