亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

初始化周期錯誤

初始化周期錯誤

Go
慕婉清6462132 2022-03-03 19:52:24
我有自動生成的代碼。簡化版:package main// begin of Afunc main(){    ParseReader("x")}func parseInclude(fileName string) (interface{}, error) {    got, _ := ParseReader(fileName)    return got, nil}// end of Atype grammar struct {    pos   int    run  func(*parser) (interface{}, error)}var g = &grammar{    pos:  1,    run: (*parser).callonIncludeOp1,}type parser struct {    filename string    cur      current}func (p *parser) callonIncludeOp1() (interface{}, error) {    return p.cur.onIncludeOp1("x")}func (p *parser) parse(g *grammar) (val interface{}, err error) {    return g.pos, nil}type current struct {    pos  int }// Bfunc (c *current) onIncludeOp1(qfilename interface{}) (interface{}, error) {    got, _ := parseInclude("x")    return got, nil}func ParseReader(filename string) (interface{}, error) {    p := &parser{ filename: filename }    return p.parse(g)}編譯后出現錯誤./prog.go:19: initialization loop:    /home/gCDfp4/prog.go:19 g refers to    /home/gCDfp4/prog.go:25 (*parser).callonIncludeOp1 refers to    /home/gCDfp4/prog.go:36 (*current).onIncludeOp1 refers to    /home/gCDfp4/prog.go:7 parseInclude refers to    /home/gCDfp4/prog.go:41 ParseReader refers to    /home/gCDfp4/prog.go:19 g我需要在語法上進行遞歸調用,因為我有預處理器運算符“#include”來解析其他文件。因為它是自動生成的代碼,所以我只能修改塊 A 或函數 B 中的代碼。我怎樣才能打破初始化周期?
查看完整描述

1 回答

?
一只斗牛犬

TA貢獻1784條經驗 獲得超2個贊

這是包初始化的結果,其中:


依賴分析不依賴于變量的實際值,只依賴于源中對它們的詞匯引用,并進行傳遞分析。


例如,如果一個變量x的初始化表達式引用了一個函數,該函數的主體引用了變量,y那么x依賴于y.


如:“對變量或函數的引用是表示該變量或函數的標識符?!?/p>


您在操場上的示例返回更直接的內容:


tmp/sandbox395359317/main.go:21: initialization loop:

    prog.go:21 g refers to

    prog.go:28 (*parser).callonIncludeOp1 refers to

    prog.go:21 g

Go 中有一些用于松散耦合的技術,例如接口。


作為一個例子(不是最優的,但至少打破了初始化周期),你可以//A添加:


type parseIncluder interface {

    parseInclude(fileName string) (interface{}, error)

}


func (c *current) parseInclude(fileName string) (interface{}, error) {

    return parseInclude(fileName)

}

在 中//B,調用parseInclude()變為:


got, _ := c.cParseIncluder().parseInclude("x")

請參閱Go plaground并單擊Run:不再initialization loop。


OP Red Skotina使用了一種不同的方法來封裝init()函數:


var gProxy grammar


func init() { gProxy = g }

func parseInclude(fileName string) (interface{}, error) {

    got, _ := ParseReaderProxy(fileName)

    return got, nil

}

func ParseReaderProxy(filename string) (interface{}, error) {

    p := &parser{filename: filename}

    return p.parse(gProxy)

}


查看完整回答
反對 回復 2022-03-03
  • 1 回答
  • 0 關注
  • 145 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號