版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
第深入探究Golang中flag標(biāo)準(zhǔn)庫(kù)的使用目錄1.使用1.1示例1.2標(biāo)志類型1.3標(biāo)志語(yǔ)法2.源碼解讀2.1定義標(biāo)志2.2解析標(biāo)志參數(shù)2.3其他代碼3.總結(jié)在使用Go進(jìn)行開(kāi)發(fā)的過(guò)程中,命令行參數(shù)解析是我們經(jīng)常遇到的需求。而flag包正是一個(gè)用于實(shí)現(xiàn)命令行參數(shù)解析的Go標(biāo)準(zhǔn)庫(kù)。在本文中,我們將深入探討flag標(biāo)準(zhǔn)庫(kù)的實(shí)現(xiàn)原理和使用技巧,以幫助讀者更好地理解和掌握該庫(kù)的使用方法。
1.使用
1.1示例
flag基本使用示例代碼如下:
packagemain
import(
"flag"
"fmt"
typeflagValstruct{
valstring
func(v*flagVal)String()string{
returnv.val
func(v*flagVal)Set(sstring)error{
v.val=s
returnnil
funcmain(){
//1.使用flag.Type()返回*int類型命令行參數(shù)
varnFlag=flag.Int("n",1234,"helpmessageforflagn")
//2.使用flag.TypeVar()綁定命令行參數(shù)到int類型變量
varflagvarint
flag.IntVar(flagvar,"flagvar",1234,"helpmessageforflagvar")
//3.使用flag.Var()綁定命令行參數(shù)到實(shí)現(xiàn)了flag.Value接口的自定義類型變量
val:=flagVal{}
flag.Var(val,"val","helpmessageforval")
//解析命令行參數(shù)
flag.Parse()
fmt.Printf("nFlag:%d\n",*nFlag)
fmt.Printf("flagvar:%d\n",flagvar)
fmt.Printf("val:%+v\n",val)
fmt.Printf("NFlag:%v\n",flag.NFlag())//返回已設(shè)置的命令行標(biāo)志個(gè)數(shù)
fmt.Printf("NArg:%v\n",flag.NArg())//返回處理完標(biāo)志后剩余的參數(shù)個(gè)數(shù)
fmt.Printf("Args:%v\n",flag.Args())//返回處理完標(biāo)志后剩余的參數(shù)列表
fmt.Printf("Arg(1):%v\n",flag.Arg(1))//返回處理完標(biāo)志后剩余的參數(shù)列表中第i項(xiàng)
}
可以通過(guò)指定--help/-h參數(shù)來(lái)查看這個(gè)命令行程序的使用幫助:
$gorunmain.go-h
Usageof./main:
-flagvarint
helpmessageforflagvar(default1234)
-nint
helpmessageforflagn(default1234)
-valvalue
helpmessageforval
這個(gè)程序接收三個(gè)命令行參數(shù):
int類型的-flagvar,默認(rèn)值為2134。int類型的-n,默認(rèn)值為2134。value類型的-val,無(wú)默認(rèn)值。
我們可以將-flagvar、-n、-val稱作flag,即「標(biāo)志」,這也是Go內(nèi)置命令行參數(shù)解析庫(kù)被命名為flag的原因,見(jiàn)名知意。
這三個(gè)參數(shù)在示例代碼中,分別使用了三種不同形式來(lái)指定:
flag.Type():
-n標(biāo)志是使用varnFlag=flag.Int(n,1234,helpmessageforflagn)來(lái)指定的。
flag.Int函數(shù)簽名如下:
funcInt(namestring,valueint,usagestring)*int
flag.Int函數(shù)接收三個(gè)參數(shù),分別是標(biāo)志名稱、標(biāo)志默認(rèn)參數(shù)值、標(biāo)志使用幫助信息。函數(shù)最終還會(huì)返回一個(gè)*int類型的值,表示用戶在執(zhí)行命令行程序時(shí)為這個(gè)標(biāo)志指定的參數(shù)。
除了使用flag.Int來(lái)設(shè)置int類型標(biāo)志,flag還支持其他多種類型,如使用flag.String來(lái)設(shè)置string類型標(biāo)志。
flag.TypeVar():
-flagvar標(biāo)志是使用flag.IntVar(flagvar,flagvar,1234,helpmessageforflagvar)來(lái)指定的。
flag.IntVar函數(shù)簽名如下:
funcIntVar(p*int,namestring,valueint,usagestring)
與flag.Int不同的是,flag.IntVar函數(shù)取消了返回值,而是會(huì)將用戶傳遞的命令行參數(shù)綁定到第一個(gè)參數(shù)p*int。
除了使用flag.IntVar來(lái)綁定int類型參數(shù)到標(biāo)志,flag還提供其他多個(gè)函數(shù)來(lái)支持綁定不同類型參數(shù)到標(biāo)志,如使用flag.StringVar來(lái)綁定string類型標(biāo)志。
flag.Var():
-val標(biāo)志是使用flag.Var(val,val,helpmessageforval)來(lái)指定的。
flag.Var函數(shù)簽名如下:
funcVar(valueValue,namestring,usagestring)
flag.Var函數(shù)接收三個(gè)參數(shù),后兩個(gè)參數(shù)分別是標(biāo)志名稱、標(biāo)志使用幫助信息。而用戶傳遞的命令行參數(shù)將被綁定到第一個(gè)參數(shù)value。
typeValueinterface{
String()string
Set(string)error
}
我們可以自定義類型,只要實(shí)現(xiàn)了flag.Value接口,都可以傳遞給flag.Var,這極大的增加了flag包的靈活性。
定義完三個(gè)標(biāo)志,我們還需要使用flag.Parse()來(lái)解析命令行參數(shù),只有解析成功以后,才會(huì)將戶傳遞的命令行參數(shù)值綁定到對(duì)應(yīng)的標(biāo)志變量中。之后就可以使用nFlag、flagvar、val的變量值了。
在main函數(shù)底部,使用flag.NFlag()、flag.NArg()、flag.Args()、flag.Arg(1)幾個(gè)函數(shù)獲取并展示了命令行參數(shù)相關(guān)信息。
現(xiàn)在我們嘗試給這個(gè)命令行程序傳遞幾個(gè)參數(shù)并執(zhí)行它,看下輸出結(jié)果:
$gorunmain.go-n100-valtestabcd
nFlag:100
flagvar:1234
val:{val:test}
NFlag:2
NArg:4
Args:[abcd]
Arg(1):b
我們通過(guò)-n100為-n標(biāo)志指定了參數(shù)值100,最終會(huì)被賦值給nFlag變量。
由于沒(méi)有指定flagvar標(biāo)志的參數(shù)值,所以flagvar變量會(huì)被賦予默認(rèn)值1234。
接著,我們又通過(guò)-valtest為-val標(biāo)志指定了參數(shù)值test,最終賦值給了自定義的flagVal結(jié)構(gòu)體的val字段。
因?yàn)橹辉O(shè)置了-n和-val兩個(gè)標(biāo)志的參數(shù)值,所以函數(shù)flag.NFlag()返回結(jié)果為2。
abcd四個(gè)參數(shù)由于沒(méi)有被定義,所以flag.NArg()返回結(jié)果為4。
flag.Args()返回的切片中存儲(chǔ)了abcd四個(gè)參數(shù)。
flag.Arg(1)返回切片中下標(biāo)為1位置的參數(shù),即b。
1.2標(biāo)志類型
在上面的示例中,我們展示了int類型和自定義的flag.Value的使用,flag包支持的所有標(biāo)志類型匯總?cè)缦拢?/p>
參數(shù)類型合法值boolstrconv.ParseBool能夠解析的有效值,接受:1,0,t,f,T,F,true,false,TRUE,FALSE,True,False。time.Durationtime.ParseDuration能夠解析的有效值,如:300ms,-1.5hor2h45m,合法單位:ns,us(ors),ms,s,m,h。float64合法的浮點(diǎn)數(shù)類型。int/int64/uint/uint64合法的整數(shù)類型,如:1234,0664,0x1234,也可以是負(fù)數(shù)。string合法的字符串類型。flag.Value實(shí)現(xiàn)了該接口的類型。
除了支持幾種Go默認(rèn)的原生類型外,如果我們想實(shí)現(xiàn)其他類型標(biāo)志的定義,都可以通過(guò)flag.Value接口類型來(lái)完成。其實(shí)flag包內(nèi)部對(duì)于bool、int等所有類型的定義,都實(shí)現(xiàn)了flag.Value接口,在稍后講解源碼過(guò)程中將會(huì)有所體現(xiàn)。
1.3標(biāo)志語(yǔ)法
命令行標(biāo)志支持多種語(yǔ)法:
語(yǔ)法說(shuō)明-flagbool類型標(biāo)志可以使用,表示參數(shù)值為true。flag支持兩個(gè)-字符,與-flag等價(jià)。-flag=x所有類型通用,為標(biāo)志flag傳遞參數(shù)值x。-flagx作用等價(jià)于-flag=x,但是僅限非bool類型標(biāo)志使用,假如這樣使用cmd-x*,其中*是Unixshell通配符,如果存在名為0、false等文件,則參數(shù)值結(jié)果會(huì)發(fā)生變化。
flag解析參數(shù)時(shí)會(huì)在第一個(gè)非標(biāo)志參數(shù)之前(單獨(dú)的一個(gè)-字符也是非標(biāo)志參數(shù))或終止符--之后停止。
2.源碼解讀
注意:本文以Go1.19.4源碼為例,其他版本可能存在差異。
熟悉了flag包的基本使用,接下來(lái)我們就要深入到flag的源碼,來(lái)探究其內(nèi)部是如何實(shí)現(xiàn)。
閱讀flag包的源碼,我們可以從使用flag包的流程來(lái)入手。
2.1定義標(biāo)志
在main函數(shù)中,我們首先通過(guò)如下代碼定義了一個(gè)標(biāo)志-n。
varnFlag=flag.Int("n",1234,"helpmessageforflagn")
flag.Int函數(shù)定義如下:
funcInt(namestring,valueint,usagestring)*int{
returnCommandLine.Int(name,value,usage)
}
可以發(fā)現(xiàn),flag.Int函數(shù)調(diào)用并返回了CommandLine對(duì)象的Int方法,并將參數(shù)原樣傳遞進(jìn)去。
來(lái)看看CommandLine是個(gè)什么:
varCommandLine=NewFlagSet(os.Args[0],ExitOnError)
funcNewFlagSet(namestring,errorHandlingErrorHandling)*FlagSet{
f:=FlagSet{
name:name,
errorHandling:errorHandling,
f.Usage=f.defaultUsage
returnf
}
CommandLine是使用NewFlagSet創(chuàng)建的FlagSet結(jié)構(gòu)體指針,在構(gòu)造FlagSet對(duì)象時(shí),需要兩個(gè)參數(shù)os.Args[0]和ExitOnError。
我們知道os.Args存儲(chǔ)了程序執(zhí)行時(shí)指定的所有命令行參數(shù),os.Args[0]就是當(dāng)前命令行程序的名稱,ExitOnError是一個(gè)常量,用來(lái)標(biāo)記在出現(xiàn)error時(shí)應(yīng)該如何做,ExitOnError表示在遇到error時(shí)退出程序。
來(lái)看下FlagSet是如何定義:
typeFlagSetstruct{
Usagefunc()
namestring
parsedbool
actualmap[string]*Flag
formalmap[string]*Flag
args[]string//argumentsafterflags
errorHandlingErrorHandling
outputio.Writer//nilmeansstderr;useOutput()accessor
}
Usage字段是一個(gè)函數(shù),根據(jù)名字大概能夠猜測(cè)出,這個(gè)函數(shù)會(huì)在指定--help/-h參數(shù)查看命令行程序使用幫助時(shí)被調(diào)用。
parsed用來(lái)標(biāo)記是否調(diào)用過(guò)flag.Parse()。
actual和formal分別用來(lái)存儲(chǔ)從命令行解析的標(biāo)志參數(shù)和在程序中指定的默認(rèn)標(biāo)志參數(shù)。它們都使用map來(lái)存儲(chǔ)Flag類型的指針,F(xiàn)lagSet可以看作是Flag結(jié)構(gòu)體的「集合」。
args用來(lái)保存處理完標(biāo)志后剩余的參數(shù)列表。
errorHandling標(biāo)記在出現(xiàn)error時(shí)應(yīng)該如何做。
output用來(lái)設(shè)置輸出位置,這可以改變--help/-h時(shí)展示幫助信息的輸出位置。
現(xiàn)在來(lái)看下Flag的定義:
typeFlagstruct{
Namestring//標(biāo)志名稱
Usagestring//幫助信息
ValueValue//標(biāo)志所對(duì)應(yīng)的命令行參數(shù)值
DefValuestring//用來(lái)記錄字符串類型的默認(rèn)值,它不會(huì)被改變
}
Flag用來(lái)記錄一個(gè)命令行參數(shù),里面存儲(chǔ)了一個(gè)標(biāo)志所有信息。
可以說(shuō)Flag和FlagSet兩個(gè)結(jié)構(gòu)體就是flag包的核心,所有功能都是圍繞這兩個(gè)結(jié)構(gòu)體設(shè)計(jì)的。
標(biāo)志所對(duì)應(yīng)的命令行參數(shù)值為flag.Value接口類型,在前文中已經(jīng)見(jiàn)過(guò)了,定義如下:
typeValueinterface{
String()string
Set(string)error
}
之所以使用接口,是為了能夠存儲(chǔ)任何類型的值,除了flag包默認(rèn)支持的內(nèi)置類型,用戶也可以定義自己的類型,只要實(shí)現(xiàn)了Value接口即可。
如我們?cè)谇拔氖纠绦蛑卸x的flagVal類型。
現(xiàn)在CommandLine的定義以及內(nèi)部實(shí)現(xiàn)我們都看過(guò)了,是時(shí)候回過(guò)頭來(lái)看一看CommandLine對(duì)象的Int方法了:
func(f*FlagSet)Int(namestring,valueint,usagestring)*int{
p:=new(int)
f.IntVar(p,name,value,usage)
returnp
}
Int方法內(nèi)部調(diào)用了f.IntVar()方法,定義如下:
func(f*FlagSet)IntVar(p*int,namestring,valueint,usagestring){
f.Var(newIntValue(value,p),name,usage)
}
IntVar方法又調(diào)用了f.Var()方法。
Var方法第一個(gè)參數(shù)為newIntValue(value,p),我們來(lái)看看newIntValue函數(shù)是如何定義的:
typeintValueint
funcnewIntValue(valint,p*int)*intValue{
*p=val
return(*intValue)(p)
func(i*intValue)Set(sstring)error{
v,err:=strconv.ParseInt(s,0,strconv.IntSize)
iferr!=nil{
err=numError(err)
*i=intValue(v)
returnerr
func(i*intValue)Get()any{returnint(*i)}
func(i*intValue)String()string{returnstrconv.Itoa(int(*i))}
newIntValue是一個(gè)構(gòu)造函數(shù),用來(lái)創(chuàng)建一個(gè)intValue類型的指針,intValue底層類型實(shí)際上是int。
定義intValue類型的目的就是為了實(shí)現(xiàn)flag.Value接口。
再來(lái)看下Var方法如何定義:
func(f*FlagSet)Var(valueValue,namestring,usagestring){
//Flagmustnotbegin"-"orcontain"=".
ifstrings.HasPrefix(name,"-"){
panic(f.sprintf("flag%qbeginswith-",name))
}elseifstrings.Contains(name,"="){
panic(f.sprintf("flag%qcontains=",name))
//Rememberthedefaultvalueasastring;itwon'tchange.
flag:=Flag{name,usage,value,value.String()}
_,alreadythere:=f.formal[name]
ifalreadythere{
varmsgstring
if==""{
msg=f.sprintf("flagredefined:%s",name)
}else{
msg=f.sprintf("%sflagredefined:%s",,name)
panic(msg)//Happensonlyifflagsaredeclaredwithidenticalnames
iff.formal==nil{
f.formal=make(map[string]*Flag)
f.formal[name]=flag
}
name參數(shù)即為標(biāo)志名,在Var方法內(nèi)部,首先對(duì)標(biāo)志名的合法性進(jìn)行了校驗(yàn),不能以-開(kāi)頭且不包含=。
接著,根據(jù)參數(shù)創(chuàng)建了一個(gè)Flag類型,并且校驗(yàn)了標(biāo)志是否被重復(fù)定義。
最后將Flag保存在formal屬性中。
到這里,整個(gè)函數(shù)調(diào)用關(guān)系就結(jié)束了,我們來(lái)梳理一下代碼執(zhí)行流程:
flag.Int-CommandLine.Int-CommandLine.IntVar-CommandLine.Var。
經(jīng)過(guò)這個(gè)調(diào)用過(guò)程,我們就得到了一個(gè)Flag對(duì)象,其名稱為n、默認(rèn)參數(shù)值為1234、值的類型為intValue、幫助信息為helpmessageforflagn。并將這個(gè)Flag對(duì)象保存在了CommandLine這個(gè)類型為FlagSet的結(jié)構(gòu)體指針對(duì)象的formal屬性中。
我們?cè)谑纠绦蛑羞€使用了另外兩種方式定義標(biāo)志。
使用flag.IntVar(flagvar,flagvar,1234,helpmessageforflagvar)定義標(biāo)志-flagvar。
flag.IntVar定義如下:
funcIntVar(p*int,namestring,valueint,usagestring){
CommandLine.Var(newIntValue(value,p),name,usage)
}
可以發(fā)現(xiàn),flag.IntVar函數(shù)內(nèi)部沒(méi)有調(diào)用CommandLine.Int和CommandLine.IntVar的過(guò)程,而是直接調(diào)用CommandLine.Var。
另外,我們還使用flag.Var(val,val,helpmessageforval)定義了-val標(biāo)志。
flag.Var定義如下:
funcVar(valueValue,namestring,usagestring){
CommandLine.Var(value,name,usage)
}
flag.Var函數(shù)內(nèi)部同樣直接調(diào)用了CommandLine.Var,并且由于參數(shù)value已經(jīng)是Value接口類型,可以無(wú)需調(diào)用newIntValue這類構(gòu)造函數(shù)將Go內(nèi)置類型轉(zhuǎn)為Value類型,直接傳遞參數(shù)即可。
2.2解析標(biāo)志參數(shù)
命令行參數(shù)定義完成了,終于到了解析部分,可以使用flag.Parse()解析命令行參數(shù)。
flag.Parse函數(shù)代碼如下:
funcParse(){
CommandLine.Parse(os.Args[1:])
}
內(nèi)部同樣是調(diào)用CommandLine對(duì)象對(duì)應(yīng)的方法,并且將除程序名稱以外的命令行參數(shù)都傳遞到Parse方法中,Parse方法定義如下:
func(f*FlagSet)Parse(arguments[]string)error{
f.parsed=true
f.args=arguments
for{
seen,err:=f.parseOne()
ifseen{
continue
iferr==nil{
break
switchf.errorHandling{
caseContinueOnError:
returnerr
caseExitOnError:
iferr==ErrHelp{
os.Exit(0)
os.Exit(2)
casePanicOnError:
panic(err)
returnnil
}
首先將f.parsed標(biāo)記為true,在調(diào)用f.Parsed()方法時(shí)會(huì)被返回:
func(f*FlagSet)Parsed()bool{
returnf.parsed
}
接著又將arguments保存在f.args屬性中。
然后就是循環(huán)解析命令行參數(shù)的過(guò)程,每調(diào)用一次f.parseOne()解析一個(gè)標(biāo)志,直到解析完成或遇到error退出程序。
parseOne方法實(shí)現(xiàn)如下:
func(f*FlagSet)parseOne()(bool,error){
iflen(f.args)==0{
returnfalse,nil
s:=f.args[0]
iflen(s)2||s[0]!='-'{
returnfalse,nil
numMinuses:=1
ifs[1]=='-'{
numMinuses++
iflen(s)==2{//"--"terminatestheflags
f.args=f.args[1:]
returnfalse,nil
name:=s[numMinuses:]
iflen(name)==0||name[0]=='-'||name[0]=='='{
returnfalse,f.failf("badflagsyntax:%s",s)
//it'saflag.doesithaveanargument
f.args=f.args[1:]
hasValue:=false
value:=""
fori:=1;ilen(name);i++{//equalscannotbefirst
ifname[i]=='='{
value=name[i+1:]
hasValue=true
name=name[0:i]
break
m:=f.formal
flag,alreadythere:=m[name]//BUG
if!alreadythere{
ifname=="help"||name=="h"{//specialcasefornicehelpmessage.
f.usage()
returnfalse,ErrHelp
returnfalse,f.failf("flagprovidedbutnotdefined:-%s",name)
iffv,ok:=flag.Value.(boolFlag);okfv.IsBoolFlag(){//specialcase:doesn'tneedanarg
ifhasValue{
iferr:=fv.Set(value);err!=nil{
returnfalse,f.failf("invalidbooleanvalue%qfor-%s:%v",value,name,err)
}else{
iferr:=fv.Set("true");err!=nil{
returnfalse,f.failf("invalidbooleanflag%s:%v",name,err)
}else{
//Itmusthaveavalue,whichmightbethenextargument.
if!hasValuelen(f.args)0{
//valueisthenextarg
hasValue=true
value,f.args=f.args[0],f.args[1:]
if!hasValue{
returnfalse,f.failf("flagneedsanargument:-%s",name)
iferr:=flag.Value.Set(value);err!=nil{
returnfalse,f.failf("invalidvalue%qforflag-%s:%v",value,name,err)
溫馨提示
- 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ì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 統(tǒng)編版2025-2026學(xué)年語(yǔ)文四年級(jí)第一學(xué)期期末質(zhì)量檢測(cè)練習(xí)卷(含答案)
- 湖南省岳陽(yáng)市汨羅市2025-2026學(xué)年八年級(jí)上學(xué)期1月期末生物試題(無(wú)答案)
- 河南省駐馬店市泌陽(yáng)縣2025-2026學(xué)年八年級(jí)上學(xué)期1月期末考試歷史試卷答案
- 2025-2026學(xué)年一年級(jí)(上)期末游戲化測(cè)試語(yǔ)文試卷(附參考答案)
- 五年級(jí)題目及答案
- 文件筐測(cè)試題及答案
- 2026年小學(xué)語(yǔ)文模擬沖刺押題卷
- 誠(chéng)實(shí)做事的演講稿
- 冀教版三年級(jí)上冊(cè)數(shù)學(xué)第二單元-兩、三位數(shù)乘一位數(shù)-測(cè)試卷及答案(奪冠系列)
- 高中高二下學(xué)期地理期末考試試題答案解析
- 2026廣東廣州市海珠區(qū)住房和建設(shè)局招聘雇員7人筆試參考題庫(kù)及答案解析
- 云南師大附中2026屆高三1月高考適應(yīng)性月考卷英語(yǔ)(六)含答案
- 海南2025年中國(guó)熱帶農(nóng)業(yè)科學(xué)院橡膠研究所第一批招聘16人(第1號(hào))筆試歷年參考題庫(kù)附帶答案詳解
- 2025-2026人教版數(shù)學(xué)七年級(jí)上冊(cè)期末模擬試卷(含答案)
- 2026年九江市八里湖新區(qū)國(guó)有企業(yè)面向社會(huì)公開(kāi)招聘工作人員【48人】筆試參考題庫(kù)及答案解析
- 廣告行業(yè)法律法規(guī)與行業(yè)規(guī)范(標(biāo)準(zhǔn)版)
- 2025年CFA二級(jí)道德與專業(yè)標(biāo)準(zhǔn)題
- 2026年鄭州電力高等??茖W(xué)校單招職業(yè)技能測(cè)試題庫(kù)新版
- 2026年八年級(jí)物理上冊(cè)期末考試試卷及答案(共四套)
- 節(jié)能與新能源汽車技術(shù)路線圖2.0
- 保育員配合教學(xué)培訓(xùn)工作指南
評(píng)論
0/150
提交評(píng)論