// Error is part of the error interface.
func(aggaggregate)Error()string{//確認一下 error slice 長度,在 new function 的時候就確認過理論上不會出錯
iflen(agg)==0{// This should never happen, really.
return""}//如果錯誤只有一個的話就回傳那一個
iflen(agg)==1{returnagg[0].Error()}// new 一個errs set
seenerrs:=sets.NewString()result:=""//需要搭配下面一點的 visit function 來看~
//visit 代表訪問每一個 item
agg.visit(func(errerror)bool{// 印出錯誤
msg:=err.Error()// 如果errs set 有包含這個錯誤的話就回傳 false(表示錯誤重複了)
ifseenerrs.Has(msg){returnfalse}//把錯誤加入 error set
seenerrs.Insert(msg)//如果錯誤大於一個需要用,分割錯誤
iflen(seenerrs)>1{result+=", "}result+=msgreturnfalse})//只有一個錯誤,直接回傳錯誤不需要加[]
iflen(seenerrs)==1{returnresult}//錯誤是一個陣列,需要加[]
return"["+result+"]"}//訪問每一個錯誤透過傳入的 function 來處理每個錯誤
func(aggaggregate)visit(ffunc(errerror)bool)bool{// 遞迴全部的錯誤
for_,err:=rangeagg{//判斷錯誤類型
switcherr:=err.(type){//如錯錯誤是一個 aggregate 的物件的話
caseaggregate://表示這個錯誤裡面包了其他錯誤,需要再展開遞迴的處理
ifmatch:=err.visit(f);match{returnmatch}//如錯錯誤是一個實作 aggregate interface 的物件的話
caseAggregate://等等會看到 Errors ,簡單來說就是把錯誤展開成一個slice
//檢查每一個錯誤
for_,nestedErr:=rangeerr.Errors(){ifmatch:=f(nestedErr);match{returnmatch}}//如果是一般錯誤的話
default://檢查個錯誤
ifmatch:=f(err);match{returnmatch}}}returnfalse}
// Flatten takes an Aggregate, which may hold other Aggregates in arbitrary
// nesting, and flattens them all into a single Aggregate, recursively.
funcFlatten(aggAggregate)Aggregate{//建立一個 error slice
result:=[]error{}//判斷 Aggregate 存不存在,不存在可以直接回傳
ifagg==nil{returnnil}//把 Aggregate 展開成 errors slice 並且遞迴所有error
for_,err:=rangeagg.Errors(){//如果判斷到 error 是 Aggregate 就要繼續遞迴展開
ifa,ok:=err.(Aggregate);ok{//遞迴展開的error結果加入到result內
r:=Flatten(a)ifr!=nil{result=append(result,r.Errors()...)}}else{//error結果加入到result內
iferr!=nil{result=append(result,err)}}}//回傳一個 Aggregate error slice
returnNewAggregate(result)}
// Reduce will return err or, if err is an Aggregate and only has one item, the first item in the aggregate.
//輸入一個error
funcReduce(errerror)error{//如過error 有實作 Aggregate 的話 ,要接著判斷 errors slice 的長度
ifagg,ok:=err.(Aggregate);ok&&err!=nil{switchlen(agg.Errors()){//如果長度是1回傳第一個錯誤
case1:returnagg.Errors()[0]//不然就是nil
case0:returnnil}}returnerr}