首頁 >後端開發 >Golang >掌握 Emacs 中的 Golang 調試

掌握 Emacs 中的 Golang 調試

Linda Hamilton
Linda Hamilton原創
2024-12-02 11:56:09206瀏覽

介紹

自從我開始使用 Golang 開發以來,我並沒有真正使用過調試器。相反,我天真地在各處添加 fmt.Print 語句來驗證我的程式碼?雖然列印語句和日誌可能也是您的第一個調試本能,但在處理大型且複雜的程式碼庫、複雜的運行時行為以及(當然!)似乎無法重現的複雜並發問題時,它們通常會出現不足。

開始處理更複雜的專案(例如這個:https://github.com/cloudoperators/heureka)後,我必須強迫自己更深入地了解delve(Golang 偵錯器)並了解Emacs 提供的功能與它互動。雖然 Go 生態系統提供了出色的調試工具,但將它們整合到舒適的開發工作流程中可能具有挑戰性。

在這篇文章中,我將詳細闡述 Emacs、Delve 和 dape 的強大組合。這些工具共同創造了模仿(並且常常超越)傳統 IDE 的調試體驗,同時保留了 Emacs 聞名的靈活性和可擴展性。

這是你所期望的:

  • 使用 dape 設定和設定 Delve
  • 調試標準應用程式和 Ginkgo 測試(這就是我目前正在使用的?)
  • 使用 Emacs 特定的自訂功能來最佳化您的偵錯工作流程

設定開發環境

在這篇文章中,我假設您已經有一些 Emacs 經驗,現在了解如何配置套件和編寫小的 Elisp 片段。我個人使用Straight.el 作為套件管理器,minimal-emacs.d 作為最小的普通Emacs 配置(以及我自己的自訂),dape 作為調試適配器客戶端,eglot 作為我的LSP 客戶端

所需的 Emacs 軟體包

對於 Emacs 29 用戶,eglot 是內建的。看看為 gopls 設定 eglot 和一些更進階的 gopls 設定。我們先加入 dape:

(use-package dape
  :straight t
  :config
  ;; Pulse source line (performance hit)
  (add-hook 'dape-display-source-hook 'pulse-momentary-highlight-one-line)

  ;; To not display info and/or buffers on startup
  ;; (remove-hook 'dape-start-hook 'dape-info)
  (remove-hook 'dape-start-hook 'dape-repl))

和運行模式:

(use-package go-mode
  :straight t
  :mode "\.go\'"
  :hook ((before-save . gofmt-before-save))
  :bind (:map go-mode-map
              ("M-?" . godoc-at-point)
              ("M-." . xref-find-definitions)
              ("M-_" . xref-find-references)
              ;; ("M-*" . pop-tag-mark) ;; Jump back after godef-jump
              ("C-c m r" . go-run))
  :custom
  (gofmt-command "goimports"))

安裝所需的 Go 工具

安裝 Delve 和 gopls(LSP 伺服器):

# Install Delve
go install github.com/go-delve/delve/cmd/dlv@latest

# Install gopls
go install golang.org/x/tools/gopls@latest

此外,我還有一些我不時使用的其他工具:

go install github.com/golangci/golangci-lint/cmd/golangci-lint@latest
go install github.com/onsi/ginkgo/v2/ginkgo@latest

go install -v golang.org/x/tools/cmd/godoc@latest
go install -v golang.org/x/tools/cmd/goimports@latest
go install -v github.com/stamblerre/gocode@latest
go install -v golang.org/x/tools/cmd/gorename@latest
go install -v golang.org/x/tools/cmd/guru@latest
go install -v github.com/cweill/gotests/...@latest

go install -v github.com/davidrjenni/reftools/cmd/fillstruct@latest
go install -v github.com/fatih/gomodifytags@latest
go install -v github.com/godoctor/godoctor@latest
go install -v github.com/haya14busa/gopkgs/cmd/gopkgs@latest
go install -v github.com/josharian/impl@latest
go install -v github.com/rogpeppe/godef@latest

然後需要配置對應的Emacs套件:

(use-package ginkgo
  :straight (:type git :host github :repo "garslo/ginkgo-mode")
  :init
  (setq ginkgo-use-pwd-as-test-dir t
        ginkgo-use-default-keys t))

(use-package gotest
  :straight t
  :after go-mode
  :bind (:map go-mode-map
              ("C-c t f" . go-test-current-file)
              ("C-c t t" . go-test-current-test)
              ("C-c t j" . go-test-current-project)
              ("C-c t b" . go-test-current-benchmark)
              ("C-c t c" . go-test-current-coverage)
              ("C-c t x" . go-run)))

(use-package go-guru
  :straight t
  :hook
  (go-mode . go-guru-hl-identifier-mode))

(use-package go-projectile
  :straight t
  :after (projectile go-mode))

(use-package flycheck-golangci-lint
  :straight t
  :hook
  (go-mode . flycheck-golangci-lint-setup))

(use-package go-eldoc
  :straight t
  :hook
  (go-mode . go-eldoc-setup))

(use-package go-tag
  :straight t
  :bind (:map go-mode-map
              ("C-c t a" . go-tag-add)
              ("C-c t r" . go-tag-remove))
  :init (setq go-tag-args (list "-transform" "camelcase")))

(use-package go-fill-struct
  :straight t)

(use-package go-impl
  :straight t)

(use-package go-playground
  :straight t)

戴普配置

我使用 dape 而不是 dap 沒有什麼特別的原因。當我還在使用 MinEmacs 時,它就是其中的一部分,我只是習慣了它。如文件所述:

  • Dape 不支援 launch.json 文件,如果需要每個項目配置,請使用 dir-locals 和 dape-command。
  • Dape 允許使用者使用選項修改或新增 PLIST 條目到現有配置,從而增強了迷你緩衝區內的人體工學。
  • 沒有魔法,沒有像 ${workspaceFolder} 這樣的特殊變數。相反,函數和變數會在開始新會話之前解析。
  • 試著設想如果 vscode 不存在,如何在 Emacs 中實現偵錯適配器配置。

如果您曾經使用過 VSCode,您已經知道它使用 launch.json 來儲存不同的偵錯設定檔:

(use-package dape
  :straight t
  :config
  ;; Pulse source line (performance hit)
  (add-hook 'dape-display-source-hook 'pulse-momentary-highlight-one-line)

  ;; To not display info and/or buffers on startup
  ;; (remove-hook 'dape-start-hook 'dape-info)
  (remove-hook 'dape-start-hook 'dape-repl))

您有不同的欄位/屬性,根據此頁面,您可以在偵錯配置中進行調整:

Property Description
name Name for your configuration that appears in the drop down in the Debug viewlet
type Always set to "go". This is used by VS Code to figure out which extension should be used for debugging your code
request Either of launch or attach. Use attach when you want to attach to an already running process
mode For launch requests, either of auto, debug, remote, test, exec. For attach requests, use either local or remote
program Absolute path to the package or file to debug when in debug & test mode, or to the pre-built binary file to debug in exec mode
env Environment variables to use when debugging. Example: { "ENVNAME": "ENVVALUE" }
envFile Absolute path to a file containing environment variable definitions
args Array of command line arguments that will be passed to the program being debugged
showLog Boolean indicating if logs from delve should be printed in the debug console
logOutput Comma separated list of delve components for debug output
buildFlags Build flags to be passed to the Go compiler
remotePath Absolute path to the file being debugged on the remote machine
processId ID of the process that needs debugging (for attach request with local mode)

申請樣本

現在讓我們透過調試實作 REST API 的真實應用程式來將我們的知識付諸實踐。

專案結構

我們的範例是用於任務管理的 REST API,其架構如下:

(use-package dape
  :straight t
  :config
  ;; Pulse source line (performance hit)
  (add-hook 'dape-display-source-hook 'pulse-momentary-highlight-one-line)

  ;; To not display info and/or buffers on startup
  ;; (remove-hook 'dape-start-hook 'dape-info)
  (remove-hook 'dape-start-hook 'dape-repl))

核心組件

讓我們來看看核心元件

任務代表我們的核心領域模型:

(use-package go-mode
  :straight t
  :mode "\.go\'"
  :hook ((before-save . gofmt-before-save))
  :bind (:map go-mode-map
              ("M-?" . godoc-at-point)
              ("M-." . xref-find-definitions)
              ("M-_" . xref-find-references)
              ;; ("M-*" . pop-tag-mark) ;; Jump back after godef-jump
              ("C-c m r" . go-run))
  :custom
  (gofmt-command "goimports"))

TaskStore 處理我們的記憶體資料操作:

# Install Delve
go install github.com/go-delve/delve/cmd/dlv@latest

# Install gopls
go install golang.org/x/tools/gopls@latest

休息API

API 公開以下端點:

  • POST /task/create - 建立一個新任務
  • GET /task/get?id=; - 透過ID擷取任務
go install github.com/golangci/golangci-lint/cmd/golangci-lint@latest
go install github.com/onsi/ginkgo/v2/ginkgo@latest

go install -v golang.org/x/tools/cmd/godoc@latest
go install -v golang.org/x/tools/cmd/goimports@latest
go install -v github.com/stamblerre/gocode@latest
go install -v golang.org/x/tools/cmd/gorename@latest
go install -v golang.org/x/tools/cmd/guru@latest
go install -v github.com/cweill/gotests/...@latest

go install -v github.com/davidrjenni/reftools/cmd/fillstruct@latest
go install -v github.com/fatih/gomodifytags@latest
go install -v github.com/godoctor/godoctor@latest
go install -v github.com/haya14busa/gopkgs/cmd/gopkgs@latest
go install -v github.com/josharian/impl@latest
go install -v github.com/rogpeppe/godef@latest

伺服器

這是伺服器實作:

(use-package ginkgo
  :straight (:type git :host github :repo "garslo/ginkgo-mode")
  :init
  (setq ginkgo-use-pwd-as-test-dir t
        ginkgo-use-default-keys t))

(use-package gotest
  :straight t
  :after go-mode
  :bind (:map go-mode-map
              ("C-c t f" . go-test-current-file)
              ("C-c t t" . go-test-current-test)
              ("C-c t j" . go-test-current-project)
              ("C-c t b" . go-test-current-benchmark)
              ("C-c t c" . go-test-current-coverage)
              ("C-c t x" . go-run)))

(use-package go-guru
  :straight t
  :hook
  (go-mode . go-guru-hl-identifier-mode))

(use-package go-projectile
  :straight t
  :after (projectile go-mode))

(use-package flycheck-golangci-lint
  :straight t
  :hook
  (go-mode . flycheck-golangci-lint-setup))

(use-package go-eldoc
  :straight t
  :hook
  (go-mode . go-eldoc-setup))

(use-package go-tag
  :straight t
  :bind (:map go-mode-map
              ("C-c t a" . go-tag-add)
              ("C-c t r" . go-tag-remove))
  :init (setq go-tag-args (list "-transform" "camelcase")))

(use-package go-fill-struct
  :straight t)

(use-package go-impl
  :straight t)

(use-package go-playground
  :straight t)

讓我們來看看我們的主要功能:

{
    "name": "Launch file",
    "type": "go",
    "request": "launch",
    "mode": "auto",
    "program": "${file}"
}

建立應用程式

讓我們啟動伺服器:

taskapi/
├── go.mod
├── go.sum
├── main.go
├── task_store.go
└── task_test.go

現在從不同的終端建立一個新任務:

import (
    "fmt"
)

type Task struct {
    ID          int    `json:"id"`
    Title       string `json:"title"`
    Description string `json:"description"`
    Done        bool   `json:"done"`
}

回應:

type TaskStore struct {
    tasks  map[int]Task
    nextID int
}

func NewTaskStore() *TaskStore {
    return &TaskStore{
        tasks:  make(map[int]Task),
        nextID: 1,
    }
}

讓我們看看是否可以取得它:

// CreateTask stores a given Task internally
func (ts *TaskStore) CreateTask(task Task) Task {
    task.ID = ts.nextID
    ts.tasks[task.ID] = task
    ts.nextID++
    return task
}

// GetTask retrieves a Task by ID
func (ts *TaskStore) GetTask(id int) (Task, error) {
    task, exists := ts.tasks[id]
    if !exists {
        return Task{}, fmt.Errorf("task with id %d not found", id)
    }
    return task, nil
}

// UpdateTask updates task ID with a new Task object
func (ts *TaskStore) UpdateTask(id int, task Task) error {
    if _, exists := ts.tasks[id]; !exists {
        return fmt.Errorf("task with id %d not found", id)
    }
    task.ID = id
    ts.tasks[id] = task
    return nil
}

回應:

package main

import (
    "encoding/json"
    "fmt"
    "net/http"
)

// Server implements a web application for managing tasks
type Server struct {
    store *TaskStore
}

func (s *Server) handleCreateTask(w http.ResponseWriter, r *http.Request) {
    if r.Method != http.MethodPost {
        http.Error(w, "Method not allowed", http.StatusMethodNotAllowed)
        return
    }
    var task Task
    if err := json.NewDecoder(r.Body).Decode(&task); err != nil {
        http.Error(w, err.Error(), http.StatusBadRequest)
        return
    }

    createdTask := s.store.CreateTask(task)
    w.Header().Set("Content-Type", "application/json")
    json.NewEncoder(w).Encode(createdTask)
}

func (s *Server) handleGetTask(w http.ResponseWriter, r *http.Request) {
    if r.Method != http.MethodGet {
        http.Error(w, "Method not allowed", http.StatusMethodNotAllowed)
        return
    }
    id := 0
    fmt.Sscanf(r.URL.Query().Get("id"), "%d", &id)

    task, err := s.store.GetTask(id)
    if err != nil {
        http.Error(w, err.Error(), http.StatusNotFound)
        return
    }

    w.Header().Set("Content-Type", "application/json")
    json.NewEncoder(w).Encode(task)
}

單元測試

以下是 TaskStore 的一些單元測試(用 Ginkgo 寫):

package main

import (
    "log"
    "net/http"
)

func main() {
    store := NewTaskStore()
    server := &Server{store: store}
    http.HandleFunc("/task/create", server.handleCreateTask)
    http.HandleFunc("/task/get", server.handleGetTask)

    log.Printf("Starting server on :8080")
    log.Fatal(http.ListenAndServe(":8080", nil))
}
go build -o taskapi *.go
./taskapi
2024/11/14 07:03:48 Starting server on :8080

在 Emacs 中,我將呼叫 ginkgo-run-this-container,如以下螢幕截圖所示:

Mastering Golang Debugging in Emacs

使用 Delve 和 Dape 進行基本調試

為了除錯我們的任務 API,我們有以下方法:

  • 我們可以直接啟動應用程式並調試它
  • 我們可以附加到正在運行的進程
  • 我們可以附加到正在運行的偵錯會話

以下是不同請求類型的選項:

請求 模式 必填 可選 標題>
request mode required optional
launch debug program dlvCwd, env, backend, args, cwd, buildFlags, output, noDebug
test program dlvCwd, env, backend, args, cwd, buildFlags, output, noDebug
exec program dlvCwd, env, backend, args, cwd, noDebug
core program, corefilePath dlvCwd, env
replay traceDirPath dlvCwd, env
attach local processId backend
remote
啟動 調試 程式 dlvCwd、env、後端、args、cwd、buildFlags、輸出、noDebug 測試 程式 dlvCwd、env、後端、args、cwd、buildFlags、輸出、noDebug 執行 程式 dlvCwd、env、後端、args、cwd、noDebug 核心 程序,核心檔案路徑 dlvCwd,環境 重播 traceDirPath dlvCwd,環境 附加 本地 進程ID 後端 遠端 表>

設定檔 1:啟動應用程式

這是我們的第一個 .dir-locals.el 偵錯設定檔:

(use-package dape
  :straight t
  :config
  ;; Pulse source line (performance hit)
  (add-hook 'dape-display-source-hook 'pulse-momentary-highlight-one-line)

  ;; To not display info and/or buffers on startup
  ;; (remove-hook 'dape-start-hook 'dape-info)
  (remove-hook 'dape-start-hook 'dape-repl))

?您可能希望對 command-cwd 使用不同的值。就我而言,我想在目前不是專案的目錄中啟動調試器。 default-directory 是一個變量,它保存目前所在緩衝區的工作目錄。

開始調試:

  • 運行 dape-in​​fo 顯示偵錯資訊

Mastering Golang Debugging in Emacs

  • 使用 dape-breakpoint-toggle 建立斷點:

Mastering Golang Debugging in Emacs

使用此設定檔啟動偵錯器後,您應該在 dape-repl 緩衝區中看到:

(use-package go-mode
  :straight t
  :mode "\.go\'"
  :hook ((before-save . gofmt-before-save))
  :bind (:map go-mode-map
              ("M-?" . godoc-at-point)
              ("M-." . xref-find-definitions)
              ("M-_" . xref-find-references)
              ;; ("M-*" . pop-tag-mark) ;; Jump back after godef-jump
              ("C-c m r" . go-run))
  :custom
  (gofmt-command "goimports"))

請注意,我們沒有指定任何要偵錯的二進位檔案/檔案(我們在 .dir-locals.el 中有 :program ".")。 delve 將在啟動應用程式之前自動建置二進位檔案:

# Install Delve
go install github.com/go-delve/delve/cmd/dlv@latest

# Install gopls
go install golang.org/x/tools/gopls@latest

設定檔 2:連接到外部偵錯器

讓我們新增一個設定檔以連接到現有的偵錯會話:

go install github.com/golangci/golangci-lint/cmd/golangci-lint@latest
go install github.com/onsi/ginkgo/v2/ginkgo@latest

go install -v golang.org/x/tools/cmd/godoc@latest
go install -v golang.org/x/tools/cmd/goimports@latest
go install -v github.com/stamblerre/gocode@latest
go install -v golang.org/x/tools/cmd/gorename@latest
go install -v golang.org/x/tools/cmd/guru@latest
go install -v github.com/cweill/gotests/...@latest

go install -v github.com/davidrjenni/reftools/cmd/fillstruct@latest
go install -v github.com/fatih/gomodifytags@latest
go install -v github.com/godoctor/godoctor@latest
go install -v github.com/haya14busa/gopkgs/cmd/gopkgs@latest
go install -v github.com/josharian/impl@latest
go install -v github.com/rogpeppe/godef@latest

現在讓我們在 CLI 上啟動 偵錯器

(use-package ginkgo
  :straight (:type git :host github :repo "garslo/ginkgo-mode")
  :init
  (setq ginkgo-use-pwd-as-test-dir t
        ginkgo-use-default-keys t))

(use-package gotest
  :straight t
  :after go-mode
  :bind (:map go-mode-map
              ("C-c t f" . go-test-current-file)
              ("C-c t t" . go-test-current-test)
              ("C-c t j" . go-test-current-project)
              ("C-c t b" . go-test-current-benchmark)
              ("C-c t c" . go-test-current-coverage)
              ("C-c t x" . go-run)))

(use-package go-guru
  :straight t
  :hook
  (go-mode . go-guru-hl-identifier-mode))

(use-package go-projectile
  :straight t
  :after (projectile go-mode))

(use-package flycheck-golangci-lint
  :straight t
  :hook
  (go-mode . flycheck-golangci-lint-setup))

(use-package go-eldoc
  :straight t
  :hook
  (go-mode . go-eldoc-setup))

(use-package go-tag
  :straight t
  :bind (:map go-mode-map
              ("C-c t a" . go-tag-add)
              ("C-c t r" . go-tag-remove))
  :init (setq go-tag-args (list "-transform" "camelcase")))

(use-package go-fill-struct
  :straight t)

(use-package go-impl
  :straight t)

(use-package go-playground
  :straight t)

現在在 Emacs 中,您可以啟動 dape 並選擇 go-attach-taskapi 設定檔:

Mastering Golang Debugging in Emacs

設定檔 3:附加到正在執行的進程

在這種情況下,應用程式已經正在運行,但您想要附加偵錯器到它。首先啟動應用程式:

{
    "name": "Launch file",
    "type": "go",
    "request": "launch",
    "mode": "auto",
    "program": "${file}"
}

找出其進程ID (PID):

taskapi/
├── go.mod
├── go.sum
├── main.go
├── task_store.go
└── task_test.go

讓我們新增另一個偵錯設定檔:

import (
    "fmt"
)

type Task struct {
    ID          int    `json:"id"`
    Title       string `json:"title"`
    Description string `json:"description"`
    Done        bool   `json:"done"`
}

我們需要一個輔助函數:

type TaskStore struct {
    tasks  map[int]Task
    nextID int
}

func NewTaskStore() *TaskStore {
    return &TaskStore{
        tasks:  make(map[int]Task),
        nextID: 1,
    }
}

Mastering Golang Debugging in Emacs

現在我啟動偵錯器:

Mastering Golang Debugging in Emacs

如果我現在發送像這樣的 POST 請求:

// CreateTask stores a given Task internally
func (ts *TaskStore) CreateTask(task Task) Task {
    task.ID = ts.nextID
    ts.tasks[task.ID] = task
    ts.nextID++
    return task
}

// GetTask retrieves a Task by ID
func (ts *TaskStore) GetTask(id int) (Task, error) {
    task, exists := ts.tasks[id]
    if !exists {
        return Task{}, fmt.Errorf("task with id %d not found", id)
    }
    return task, nil
}

// UpdateTask updates task ID with a new Task object
func (ts *TaskStore) UpdateTask(id int, task Task) error {
    if _, exists := ts.tasks[id]; !exists {
        return fmt.Errorf("task with id %d not found", id)
    }
    task.ID = id
    ts.tasks[id] = task
    return nil
}

偵錯器應在設定的斷點處自動停止:

Mastering Golang Debugging in Emacs

調試 Ginkgo 測試

能夠在 Golang 中除錯測試至關重要。為了執行 ginkgo 測試,我使用 ginkgo-mode,它具有以下功能:

Mastering Golang Debugging in Emacs

Mastering Golang Debugging in Emacs

作為輸出,我得到:

(use-package dape
  :straight t
  :config
  ;; Pulse source line (performance hit)
  (add-hook 'dape-display-source-hook 'pulse-momentary-highlight-one-line)

  ;; To not display info and/or buffers on startup
  ;; (remove-hook 'dape-start-hook 'dape-info)
  (remove-hook 'dape-start-hook 'dape-repl))

銀杏的 Dape 配置

這是調試 Ginkgo 測試的基本配置:

(use-package go-mode
  :straight t
  :mode "\.go\'"
  :hook ((before-save . gofmt-before-save))
  :bind (:map go-mode-map
              ("M-?" . godoc-at-point)
              ("M-." . xref-find-definitions)
              ("M-_" . xref-find-references)
              ;; ("M-*" . pop-tag-mark) ;; Jump back after godef-jump
              ("C-c m r" . go-run))
  :custom
  (gofmt-command "goimports"))

如果我選擇 go-test-ginkgo 調試配置文件,我應該能夠調試測試:

Mastering Golang Debugging in Emacs

現在配置非常靜態,因此您無法預先選擇單元測試/容器。我們需要以某種方式讓參數 -ginkgo.focus 動態化:

# Install Delve
go install github.com/go-delve/delve/cmd/dlv@latest

# Install gopls
go install golang.org/x/tools/gopls@latest

Mastering Golang Debugging in Emacs

之後,如果我查看 dape-configs 變量,我應該會看到這個值:

go install github.com/golangci/golangci-lint/cmd/golangci-lint@latest
go install github.com/onsi/ginkgo/v2/ginkgo@latest

go install -v golang.org/x/tools/cmd/godoc@latest
go install -v golang.org/x/tools/cmd/goimports@latest
go install -v github.com/stamblerre/gocode@latest
go install -v golang.org/x/tools/cmd/gorename@latest
go install -v golang.org/x/tools/cmd/guru@latest
go install -v github.com/cweill/gotests/...@latest

go install -v github.com/davidrjenni/reftools/cmd/fillstruct@latest
go install -v github.com/fatih/gomodifytags@latest
go install -v github.com/godoctor/godoctor@latest
go install -v github.com/haya14busa/gopkgs/cmd/gopkgs@latest
go install -v github.com/josharian/impl@latest
go install -v github.com/rogpeppe/godef@latest

在 dape-repl 緩衝區中啟動偵錯器(使用以偵錯為中心的測試設定檔)後,我得到:

(use-package ginkgo
  :straight (:type git :host github :repo "garslo/ginkgo-mode")
  :init
  (setq ginkgo-use-pwd-as-test-dir t
        ginkgo-use-default-keys t))

(use-package gotest
  :straight t
  :after go-mode
  :bind (:map go-mode-map
              ("C-c t f" . go-test-current-file)
              ("C-c t t" . go-test-current-test)
              ("C-c t j" . go-test-current-project)
              ("C-c t b" . go-test-current-benchmark)
              ("C-c t c" . go-test-current-coverage)
              ("C-c t x" . go-run)))

(use-package go-guru
  :straight t
  :hook
  (go-mode . go-guru-hl-identifier-mode))

(use-package go-projectile
  :straight t
  :after (projectile go-mode))

(use-package flycheck-golangci-lint
  :straight t
  :hook
  (go-mode . flycheck-golangci-lint-setup))

(use-package go-eldoc
  :straight t
  :hook
  (go-mode . go-eldoc-setup))

(use-package go-tag
  :straight t
  :bind (:map go-mode-map
              ("C-c t a" . go-tag-add)
              ("C-c t r" . go-tag-remove))
  :init (setq go-tag-args (list "-transform" "camelcase")))

(use-package go-fill-struct
  :straight t)

(use-package go-impl
  :straight t)

(use-package go-playground
  :straight t)

?請注意,僅運行了「5 個規格中的 1 個」(❶),這表示 ginkgo 只專注於我們指定的容器 (❷)。

最佳實踐和技巧

透過我的除錯經驗,我開始欣賞一些最佳實踐:

  • 使用版本控制進行調試配置
  • 在 .dir-locals.el 中維護調試配置
  • 使用有意義的名稱進行設定
  • 建立特定於專案的偵錯輔助函數
  • 在本地進行自訂(特定於緩衝區)

資源和參考

  • vscode-go/docs/debugging.md at master · golang/vscode-go
  • 直接支援 delve/dlv dap-mode · Issue #318 · emacs-lsp/dap-mode
  • Dape GitHub 儲存庫
  • 深入調試器
  • Eglot 文件
  • Ginkgo 測試框架

以上是掌握 Emacs 中的 Golang 調試的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn