第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

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

通過靜態(tài)分析查找變量的類型?

通過靜態(tài)分析查找變量的類型?

Go
手掌心 2022-12-19 10:51:49
如何通過靜態(tài)分析判斷變量的類型?假設我有以下代碼:func doSomething(x interface{}) {}func main() {  p := Person()  doSomething(p)}而我想分析一下doSomething(person),是否可以通過靜態(tài)分析得到Person的類型?如果有多個級別的分配怎么辦?p1 := Person()p2 := p1doSomething(p2)要么parent := Parent()p := Parent.Child() // type PersondoSomething(p)用例是我有一個在整個(非常大的)代碼庫中常用的通用函數(shù),并且想引入該函數(shù)的新類型安全版本。為此,我希望自動確定函數(shù)的“類型”并相應地重構它:// oldDB.InsertRow(person)// newPerson.InsertRow(person)
查看完整描述

2 回答

?
尚方寶劍之說

TA貢獻1788條經(jīng)驗 獲得超4個贊

通過靜態(tài)分析查找表達式的類型非常重要,有時甚至是不可能的,有關詳細信息,請參閱Golang static identifier resolution。


用例是我有一個在整個(非常大的)代碼庫中常用的通用函數(shù),并且想引入該函數(shù)的新類型安全版本。為此,我希望自動確定函數(shù)的“類型”并相應地重構它:


// old

DB.InsertRow(person)


// new

Person.InsertRow(person)

僅出于重構目的,我認為不值得費心去實施它。


您可以做的是DB.InsertRow()臨時更改簽名以僅接受特定類型,例如int您確定未在任何地方使用的自定義類型(例如type tempFoo struct{})。


為了什么目的?這樣做,編譯器將為您完成艱苦的工作。您將看到錯誤消息準確顯示您的代碼庫試圖傳遞給的類型DB.InsertRow(),所以我想說任務已完成。


例如這段代碼編譯:


func doSomething(x interface{}) {}


func main() {

    doSomething(image.Pt(1, 2))

    doSomething("abc")

    doSomething(image.Rect) // image.Rect is a function which we don't call,

                            // so we're passing a value of a function type here

}

如果我們改變doSomething():


func doSomething(x int) {}

我們從編譯器中得到我們正在尋找的類型:


./prog.go:10:14: 不能使用 image.Pt(1, 2)(image.Point類型的值)作為 doSomething 參數(shù)中的 int 類型


./prog.go:11:14: 不能在 doSomething 的參數(shù)中使用“abc”(無類型字符串常量)作為 int 值


./prog.go:12:14: 不能使用 image.Rect(類型func(x0 int, y0 int, x1 int, y1 int) image.Rectangle 的值)作為 doSomething 參數(shù)中的 int 類型


查看完整回答
反對 回復 2022-12-19
?
HUX布斯

TA貢獻1876條經(jīng)驗 獲得超6個贊

使用Golang static identifier resolution to use的建議golang.org/x/tools/go/types,我發(fā)現(xiàn)這對golang.org/x/tools/go/analysis包來說非常簡單,它具有可用的類型信息以及解析的 ast。

這是我的解決方案:

package rewriter


import (

    "go/ast"


    "golang.org/x/tools/go/analysis"


    "golang.org/x/tools/go/analysis/passes/inspect"


    "golang.org/x/tools/go/ast/inspector"

)


func run(pass *analysis.Pass) (interface{}, error) {

    inspect := pass.ResultOf[inspect.Analyzer].(*inspector.Inspector)


    nodeFilter := []ast.Node{

        (*ast.CallExpr)(nil),

    }


    inspect.Nodes(nodeFilter, func(node ast.Node, push bool) bool {

        callExpr, ok := node.(*ast.CallExpr)

        if !ok {

            return true

        }


        funcExpr, ok := callExpr.Fun.(*ast.SelectorExpr)

        if !ok {

            return true

        }


        // check method name

        if funcExpr.Sel.Name != "doSomething" {

            return true

        }


        for _, arg := range callExpr.Args {

            // lookup type of the arg

            argType := pass.TypesInfo.Types[arg].Type

            if argType.String() == "*rewriter.Person" {

                // do whatever you want here

            }

        }

        return false

    })

    return nil, nil

}

可以擴充它以查看方法的接收者并根據(jù)需要添加重構邏輯(使用analysis.Diagnostic)。



查看完整回答
反對 回復 2022-12-19
  • 2 回答
  • 0 關注
  • 110 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯(lián)系客服咨詢優(yōu)惠詳情

幫助反饋 APP下載

慕課網(wǎng)APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網(wǎng)微信公眾號