




版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
四、Julia語(yǔ)言進(jìn)階4.3元編程元編程是指編程語(yǔ)言可以通過(guò)編寫(xiě)程序生成滿足用戶需求的程序。Julia語(yǔ)言把代碼表示為語(yǔ)言中的數(shù)據(jù)結(jié)構(gòu),支持元編程。在程序運(yùn)行時(shí)和編譯時(shí),元編程可以修改對(duì)象和添加方法等,使得編程更靈活。元編程的程序表示創(chuàng)建表達(dá)式并求值生成代碼利用宏實(shí)現(xiàn)元編程生成函數(shù)運(yùn)行時(shí)反射四、Julia語(yǔ)言進(jìn)階4.3.1程序表示Julia代碼的執(zhí)行過(guò)程分為兩個(gè)階段:第一將字符串解析為抽象語(yǔ)法樹(shù)結(jié)構(gòu)解析原始代碼階段和第二執(zhí)行已解析代碼階段。利用元編程可以在代碼執(zhí)行之前,對(duì)已解析的代碼進(jìn)行修改。修改后的結(jié)果類(lèi)型為Expr類(lèi)型。julia>str1="1+2""1+2"julia>expr1=Meta.parse(str1) #使用Meta.parse解析字符串:(1+2)julia>typeof(expr1) #解析輸出的結(jié)果類(lèi)型為表達(dá)式類(lèi)型Expr四、Julia語(yǔ)言進(jìn)階4.3.1程序表示Expr類(lèi)型包含符號(hào)對(duì)象和表達(dá)式,表達(dá)式可能包含符號(hào)、其它表達(dá)式或字面量。julia>fieldnames(typeof(expr1))(:head,:args)julia>s1=expr1.head#標(biāo)識(shí)表達(dá)式類(lèi)型的Symbol:calljulia>typeof(s1)Symboljulia>expr1.args#表達(dá)式參數(shù)數(shù)組3-elementVector{Any}::+12四、Julia語(yǔ)言進(jìn)階4.3.1程序表示Expr類(lèi)型包含符號(hào)對(duì)象和表達(dá)式,表達(dá)式可能包含符號(hào)、其它表達(dá)式或字面量。julia>typeof(expr1.args[1])#判斷表達(dá)式參數(shù)類(lèi)型Symboljulia>typeof(expr1.args[2])Int64julia>typeof(expr1.args[3])Int64julia>dump(expr1)#使用dump函數(shù)查看Expr對(duì)象Exprhead:Symbolcallargs:Array{Any}((3,))1:Symbol+2:Int6413:Int642四、Julia語(yǔ)言進(jìn)階4.3.1程序表示使用Expr函數(shù)構(gòu)造表達(dá)式,與parse所解析的表達(dá)式等價(jià)。julia>expr1=Meta.parse(str1) :(1+2)julia>expr2=Expr(:call,:+,1,2):(1+2)julia>expr1==expr2truejulia>s2=:sym1:sym1julia>typeof(s2)Symboljulia>s2==Symbol("sym1")true使用使用:構(gòu)造與使用Symbol函數(shù)構(gòu)造等價(jià)。四、Julia語(yǔ)言進(jìn)階4.3.1程序表示使用Symbol函數(shù)將多個(gè)字符串聯(lián)。julia>Symbol("MWORKS","_","Syslab"):MWORKS_Syslabjulia>Symbol(:MWORKS,"_","Syslab"):MWORKS_Syslabjulia>:MWORKS_Syslab:MWORKS_Syslabjulia>s3=Symbol("MWORKS",".","Syslab")Symbol("MWORKS.Syslab")julia>dump(s3)SymbolMWORKS.Syslab標(biāo)識(shí)符“_”串聯(lián)字符串無(wú)效標(biāo)識(shí)符“.”需要用雙引號(hào)。四、Julia語(yǔ)言進(jìn)階4.3.2表達(dá)式與求值通過(guò)符號(hào):構(gòu)造表達(dá)式,稱為引用。復(fù)雜表達(dá)式通過(guò)引用符號(hào)、其它表達(dá)式和字面量值構(gòu)造。julia>expr3=:(a+b/c-3):((a+b/c)-3)julia>expr3==Expr(:call,:-,Expr(:call,:+,:a,Expr(:call,:/,:b,:c)),3)true用符號(hào):構(gòu)造復(fù)雜表達(dá)式比Expr函數(shù)構(gòu)造簡(jiǎn)單。四、Julia語(yǔ)言進(jìn)階4.3.2表達(dá)式與求值使用符號(hào)$將數(shù)插入表達(dá)式,稱為插值。未被引用的表達(dá)式不能被插值。julia>c=11julia>expr4=:(a+b/$c-3)#向被引用表達(dá)式插值:((a+b/1)-3)julia>a+b/$c-3#向未被引用表達(dá)式插值ERROR:syntax:"$"expressionoutsidequotearoundREPL[61]:1Stacktrace:[1]top-levelscope@REPL[61]:1四、Julia語(yǔ)言進(jìn)階4.3.2表達(dá)式與求值將多個(gè)表達(dá)式變成另一個(gè)表達(dá)式的參數(shù)時(shí),可以使用$(name…)構(gòu)造。例如,將數(shù)組中的表達(dá)式插入到函數(shù)f的輸入?yún)?shù)位置julia>arry1=[:a,:b,:c,:d];julia>:(f(1,$(arry1:(f(1,a,b,c,d))四、Julia語(yǔ)言進(jìn)階4.3.2表達(dá)式與求值引用多個(gè)表達(dá)式,用關(guān)鍵詞quote構(gòu)造新的表達(dá)式。julia>expr5=quotex=1y=4x-yendquote#=REPL[57]:2=#x=1#=REPL[57]:3=#y=4#=REPL[57]:4=#x-yendjulia>expr6=quotequotex=1y=4x-yendendquote#=REPL[79]:2=#$(Expr(:quote,quote#=REPL[79]:3=#x=1#=REPL[79]:4=#y=4#=REPL[79]:5=#x-yend))endqutoe支持嵌套引用四、Julia語(yǔ)言進(jìn)階4.3.2表達(dá)式與求值用關(guān)鍵詞eval求取表達(dá)式的值。julia>expr7=:(2-9):(2-9)julia>eval(expr7)-7julia>expr8=:(a*b)#含未賦值變量的表達(dá)式:(a*b)julia>eval(expr8)ERROR:UndefVarError:bnotdefinedjulia>a=6;b=3;#在全局作用域內(nèi)對(duì)表達(dá)式的變量賦值julia>eval(expr8)18julia>a=3;julia>eval(expr8)9注意:未賦值的表達(dá)式不能求值。四、Julia語(yǔ)言進(jìn)階4.3.2表達(dá)式與求值先賦值的變量,用Expr構(gòu)造表達(dá)式后,變量值不可修改。julia>a9=8;julia>expr9=Expr(:call,:-,a9,:b9):(8-b9)julia>a9=0;b9=3;julia>eval(expr9)5julia>b9=4;eval(expr9)4a9值在構(gòu)造表達(dá)式之前賦值修改a9值表達(dá)式的值未改變未賦值的變量值可修改四、Julia語(yǔ)言進(jìn)階4.3.3代碼生成當(dāng)需要編寫(xiě)重復(fù)的代碼、樣板形式代碼時(shí),可以使用元編程大幅度提升編程效率。在Julia語(yǔ)言中,使用插值和求值來(lái)實(shí)現(xiàn)代碼生成。julia>op=:+;julia>quote($op)(a,b,c)=($op)(($op)(a,b),c)endquote#=REPL[28]:2=#a+b+c=begin#=REPL[28]:2=#(a+b)+cendendjulia>eval(quote($op)(a,b,c)=($op)(($op)(a,b),c)end)+(genericfunctionwith1method)用符號(hào):和和插值實(shí)現(xiàn)連加用關(guān)鍵詞引用和插值實(shí)現(xiàn)連加四、Julia語(yǔ)言進(jìn)階4.3.3代碼生成當(dāng)需要編寫(xiě)重復(fù)的代碼、樣板形式代碼時(shí),可以使用元編程大幅度提升編程效率。在Julia語(yǔ)言中,使用插值和求值來(lái)實(shí)現(xiàn)代碼生成。julia>forop=(:+,:-,:*,:/,:&&,:||)#需要多個(gè)不同的操作時(shí),用for循環(huán)。eval(quote($op)(a,b,c)=($op)(($op)(a,b),c)end)end
julia>forop=(:+,:-,:*,:/,:&&,:||)#使用符號(hào):構(gòu)造,程序更簡(jiǎn)潔。eval(:(($op)(a,b,c)=($op)(($op)(a,b),c)))endjulia>forop=(:+,:-,:*,:/,:&&,:||)#使用@eval宏。@eval($op)(a,b,c)=($op)(($op)(a,b),c)end四、Julia語(yǔ)言進(jìn)階4.3.4宏宏可以實(shí)現(xiàn)表達(dá)式的替換,不需要使用eval就可以返回表達(dá)式。用關(guān)鍵詞macro構(gòu)造宏,聲明語(yǔ)法:macromac_name(para_name)…end構(gòu)造宏,mac_name為宏名稱,para_name為輸入?yún)?shù)。julia>macromac1()#構(gòu)造無(wú)輸入?yún)?shù)的宏。return:(println("MWORKS.Syslab"))end@mac1(macrowith1method)julia>macromac2(str)#構(gòu)造有輸入?yún)?shù)的宏。return:(println("MWORKS.Syslabbasedon",$str))end@mac2(macrowith1method)四、Julia語(yǔ)言進(jìn)階4.3.4宏調(diào)用宏的2種方法@mac_namepara_name1para_name2…#使用空格分開(kāi)參數(shù)名稱。@mac_name(para_name1,para_name2…)#使用逗號(hào)分開(kāi)參數(shù)名稱。julia>macromac3(para1,para2,para3)return:(println($para1,$para2,$para3))end@mac3(macrowith1method)julia>@mac3"MWORKS.Syslab"2023"a"MWORKS.Syslab2023ajulia>@mac3("MWORKS.Syslab",2023,"a")MWORKS.Syslab2023a注意:宏名與()之間不能有空格四、Julia語(yǔ)言進(jìn)階4.3.4宏數(shù)組做參數(shù)時(shí),先將數(shù)組代入宏計(jì)算并返回值,再執(zhí)行剩余表達(dá)式。julia>macromac4(para)return:($para.+1)end@mac4(macrowith1method)julia>@mac4[12]*2#第一種調(diào)用方式,宏名和數(shù)組之間沒(méi)有空格。1×2Matrix{Int64}:46#先計(jì)算[12].+1,再計(jì)算返回值*2。julia>@mac4([12])*2#第二種調(diào)用方式,宏名和括號(hào)之間沒(méi)有空格。1×2Matrix{Int64}:46#先計(jì)算[12].+1,再計(jì)算返回值*2。julia>@mac4[12]*2#先計(jì)算[12]*2,再計(jì)算返回值.+1。1×2Matrix{Int64}:35注意:有空格時(shí),整體做為宏的輸入?yún)?shù)。四、Julia語(yǔ)言進(jìn)階4.3.4宏使用show函數(shù)可導(dǎo)出宏的參數(shù),但show函數(shù)必須在宏內(nèi)部。julia>macromac5(para)show(para)end@mac5(macrowith1method)julia>@mac5(x):xjulia>@mac5(2*3):(2*3)四、Julia語(yǔ)言進(jìn)階4.3.4宏衛(wèi)生宏,又稱為干凈宏,可避免展開(kāi)后的表達(dá)式中變量與全局變量名稱沖突的問(wèn)題。宏內(nèi)部只可使用關(guān)鍵詞local聲明局部變量,不能使用eval,可使用關(guān)鍵詞esc轉(zhuǎn)義以避免宏變大。例如計(jì)算時(shí)間的宏:macromac7(ex)returnquotelocalt0=time_ns()localval=$(esc(ex))localt1=time_ns()println("elapsedtime:",(t1-t0)/1e9,"seconds")valendend四、Julia語(yǔ)言進(jìn)階4.3.4宏宏的派發(fā),同一個(gè)宏可以有多個(gè)方法,調(diào)用宏時(shí)可以實(shí)現(xiàn)多重派發(fā)。julia>macromac8(para1)println("FirstMethod")return:(println($para1))end@mac8(macrowith1methods)julia>macromac8(para1,para2)println("SecondMethod")return:(println($para1,$para2))end@mac8(macrowith2methods)julia>@mac8("Syslab")FirstMethodSyslabjulia>@mac8(9)FirstMethod9julia>@mac8("MWORKS","Syslab")SecondMethodMWORKSSyslabSyslab程序運(yùn)行結(jié)果為:四、Julia語(yǔ)言進(jìn)階4.3.5非標(biāo)準(zhǔn)字符串字面量以標(biāo)識(shí)符為前綴的字符串字面量被稱為非標(biāo)準(zhǔn)字符串字面量。以r為前綴的正則表達(dá)式,并非是字符串。例如:r"\\Qx\\E"調(diào)用宏@r_str創(chuàng)建正則表達(dá)式j(luò)ulia>@r_str("\\Qx\\E")r"\Qx\E"julia>x=3;julia>@r_str("\\Q$x\\E")ERROR:MethodError:nomethodmatchingRegex(::Expr)julia>Regex("\\Q$x\\E")r"\Q3\E"不能利用宏直接插值,用Regex函數(shù)實(shí)現(xiàn)插值并構(gòu)造正則表達(dá)式。四、Julia語(yǔ)言進(jìn)階4.3.6生成函數(shù)宏@generated定義生成函數(shù)。生成函數(shù)與普通函數(shù)不同,調(diào)用生成函數(shù)返回的是表達(dá)式,普通函數(shù)返回的是值。定義和調(diào)用生成函數(shù)julia>@generatedfunctionfun1(x)return:(x*x)endfun1(genericfunctionwith1method)julia>fun1(5)25julia>fun1("Syslab")"SyslabSyslab"在普通函數(shù)關(guān)鍵詞function前加@generated宏。四、Julia語(yǔ)言進(jìn)階4.3.6生成函數(shù)向普通函數(shù)中添加新方法julia>fun2(x)="MWORKS";julia>@generatedfun3(x)=fun2(x);#不允許向fun2()添加新方法julia>@generatedfun4(x)=:(fun2(x));#允許向fun2()添加新方法julia>a1=fun3(1)"MWORKS"julia>b1=fun4(1)"MWORKS"julia>fun2(x::Int64)="Syslab"#添加新方法fun2(genericfunctionwith2methods)julia>a2=fun3(1)"MWORKS"julia>b2=fun4(1)"Syslab"四、Julia語(yǔ)言進(jìn)階4.3.7運(yùn)行時(shí)反射Julia的元編程支持運(yùn)行時(shí)反射,例如可以查看類(lèi)型字段、類(lèi)型的類(lèi)型、類(lèi)型的亞型,還可查看函數(shù)所包含的方法和函數(shù)內(nèi)部檢查。julia>structMytypex::Int64yendjulia>typeof(Mytype)#查看Mytype的類(lèi)型DataTypejulia>fieldnames(Mytype)#查看類(lèi)型字段(:x,:y)julia>Mytype.types#字段類(lèi)型儲(chǔ)存在types變量中svec(Int64,Any)查看類(lèi)型字段和類(lèi)型的類(lèi)型julia>subtypes(AbstractFloat)6-elementVector{An
溫馨提示
- 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 蛋品加工過(guò)程中的食品安全管理體系考核試卷
- 嵌入式云平臺(tái)的應(yīng)用試題及答案
- 織造設(shè)備的數(shù)據(jù)分析與優(yōu)化考核試卷
- 專業(yè)嵌入式考試準(zhǔn)備試題及答案
- 行政管理實(shí)操能力考核試題及答案
- 數(shù)據(jù)庫(kù)監(jiān)管合規(guī)性考查試題及答案
- 應(yīng)用程序監(jiān)控與測(cè)試的關(guān)系試題及答案
- 如何提高公路工程考試通過(guò)率試題及答案
- 計(jì)算機(jī)四級(jí)軟件測(cè)試工程師考點(diǎn)與試題及答案
- 信息系統(tǒng)監(jiān)理師全面?zhèn)淇挤桨冈囶}及答案
- 計(jì)算機(jī)組裝與維護(hù)立體化教程ppt課件(完整版)
- 痛風(fēng)性關(guān)節(jié)炎 課件
- 項(xiàng)目部管理人員名單
- 四川省廣安市中考數(shù)學(xué)真題含答案
- 送達(dá)地址確認(rèn)書(shū)(法院最新版)
- 電腦企業(yè)之 組裝作業(yè)指導(dǎo)書(shū)(DK607 Nupro760)
- 油藏?cái)?shù)值模擬實(shí)驗(yàn)報(bào)告
- 現(xiàn)金流量表(帶公式)
- 微觀經(jīng)濟(jì)學(xué)選擇題100練
- (完整word版)JIS日標(biāo)法蘭尺寸標(biāo)準(zhǔn)
- 廣元市城鎮(zhèn)生活污泥處置特許經(jīng)營(yíng)項(xiàng)目實(shí)施方案
評(píng)論
0/150
提交評(píng)論