官术网_书友最值得收藏!

1.9 多重分派

函數是一個對象,它通過對一些傳入參數進行一系列加工,最終可以返回一個返回值。當一個函數無法正確運行時,它就會拋出異常。如果你傳入的參數不同,那么自然是想用不同的函數實現不同的功能,但這些函數的功能也許很相近,這時候Julia中的多重分派功能就可以發揮作用了。

比如,我們設計了一個函數來對兩個浮點數進行求和運算,然后使用另一個函數來對兩個整數進行求和運算。因為傳入的參數不同,所以使用的是兩個不同的函數來實現的。但從概念上講,這兩個函數做了同樣的事情,就是將兩個數相加。這時使用相同的函數名去調用這兩個函數顯得簡單易用,并且更易于理解。如果使用多重分派功能,那么這兩個函數不用被同時定義,只需要在使用時添加它們就可以了,而且不同參數的函數有完全不同的實現。在調用函數時,Julia會自動根據傳入的參數關聯合適的行為,其中每一種行為的定義都被稱為方法。我們所要做的只是在調用函數時傳入不同的參數就可以了,其余的工作Julia都可以十分高效地幫你完成。

在調用函數時應用對應的方法叫作分派,在平時的使用中有兩種分派方法。

? 動態分派:基于運行時的類型推斷。

? 多重分派:基于所有的參數,而不僅僅是接收器的名稱。

Julia根據所有參數選擇調用哪個方法,這種機制被稱為多重分派。多重分派對數學和科學領域的代碼特別有用。我們不應該將一個函數局限于一組特殊類型的參數。例如,在實現一個數學運算符時會考慮所有參數類型的操作過程,而并不是只能用于一組類型。多重分派的應用場景不局限于數學表達式,它可以在許多真實場景中使用,并且能構建出優秀的程序。

“+”符號就是Julia中定義的一個使用多重分派的函數,同時Julia的所有標準函數和運算符都使用了多重分派。對于不同參數類型的各種組合,Julia提供了許多種定義不同行為的方法。比如,你可以使用“:: type-assertion”運算符讓一個函數生成一個只接受特定類型參數的方法。

01  julia> f(x::Float64, y::Float64) = x + y
02  f (generic function with 1 method)

上面這個方法只會接受兩個都是Float64類型的參數,如果提供了其他類型的參數,它會彈出一個錯誤警告:

01  julia> f(5,10.0)
02  ERROR: MethodError: no method matching f(::Int64, ::Float64)
03  Closest candidates are:
04  f(::Float64, ::Float64) at REPL[4]:1

因為所傳入的參數類型必須與函數中定義的參數類型完全相同,在定義第一個方法時會自動生成一個函數對象,之后定義新方法時,會自動添加到相應的函數對象中。在調用函數時,將自動匹配參數的數量和類型,然后執行相應的方法。下面定義另一個方法,使用兩個Number類型的參數,同樣也是將兩個參數的值相加。這樣定義后,在使用Float64類型的參數調用函數時,會自動應用第一個方法;在使用整數參數調用函數時,會自動應用第二個方法。從直觀上講,我們使用的是同一個函數名。

01  julia> f(x::Number, y::Number) = x + y
02  f (generic function with 2 methods)
03  julia> f(100,200)
04  300

在Julia中,所有值都是抽象類型Any的實例。如果沒有使用“::”指明參數的類型,那么該參數的類型就是Any,它沒有對傳入的值進行限制。如果你定義了一個函數,并且對這個函數的用途很明確,那么在該函數只含有一個方法的情況下,可以不使用“::”來約束參數類型。關于多重分派先介紹到這里,我們會在后續的章節中進行詳細研究。

主站蜘蛛池模板: 平阳县| 太和县| 丁青县| 普宁市| 祥云县| 措美县| 祁东县| 连州市| 白山市| 肇州县| 新郑市| 双牌县| 威海市| 黎川县| 越西县| 蕉岭县| 星子县| 南投市| 邵东县| 涞源县| 山西省| 平谷区| 若尔盖县| 嵩明县| 隆安县| 宁晋县| 苗栗市| 新化县| 海盐县| 吴桥县| 澄江县| 临潭县| 望谟县| 仙游县| 吐鲁番市| 马尔康县| 万宁市| 体育| 武汉市| 海安县| 资源县|