コーディング規約を追加
This commit is contained in:
parent
a4a53616ba
commit
372ba41406
@ -2,7 +2,6 @@
|
|||||||
|
|
||||||
Go言語の共通モジュールを作成する
|
Go言語の共通モジュールを作成する
|
||||||
|
|
||||||
|
|
||||||
## Go言語の特徴
|
## Go言語の特徴
|
||||||
|
|
||||||
* シンプルで学習コストが低い構造
|
* シンプルで学習コストが低い構造
|
||||||
@ -11,4 +10,10 @@ Go言語の共通モジュールを作成する
|
|||||||
* クロスコンパイルが容易 (Linux, Windows, macOS などへ簡単に出力可能)
|
* クロスコンパイルが容易 (Linux, Windows, macOS などへ簡単に出力可能)
|
||||||
* 静的型付け
|
* 静的型付け
|
||||||
* クラスを持たず、構造体とメソッドでオブジェクト指向的な書き方ができる
|
* クラスを持たず、構造体とメソッドでオブジェクト指向的な書き方ができる
|
||||||
* 標準ライブラリが強力で小さなバイナリにまとまる
|
* 標準ライブラリが強力で小さなバイナリにまとまる
|
||||||
|
|
||||||
|
## Go言語を実行する
|
||||||
|
|
||||||
|
```sh
|
||||||
|
go run src/hello.go
|
||||||
|
```
|
||||||
188
examples/api_client.go
Normal file
188
examples/api_client.go
Normal file
@ -0,0 +1,188 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
"net/http"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
// APIClient はHTTPリクエストを送信するクライアント
|
||||||
|
type APIClient struct {
|
||||||
|
BaseURL string
|
||||||
|
HTTPClient *http.Client
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewAPIClient は新しいAPIクライアントを作成
|
||||||
|
func NewAPIClient(baseURL string) *APIClient {
|
||||||
|
return &APIClient{
|
||||||
|
BaseURL: baseURL,
|
||||||
|
HTTPClient: &http.Client{
|
||||||
|
Timeout: 30 * time.Second,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get はGETリクエストを送信
|
||||||
|
func (c *APIClient) Get(endpoint string) ([]byte, error) {
|
||||||
|
url := c.BaseURL + endpoint
|
||||||
|
|
||||||
|
resp, err := c.HTTPClient.Get(url)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("GETリクエスト失敗: %w", err)
|
||||||
|
}
|
||||||
|
defer resp.Body.Close()
|
||||||
|
|
||||||
|
body, err := io.ReadAll(resp.Body)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("レスポンス読み込み失敗: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if resp.StatusCode != http.StatusOK {
|
||||||
|
return nil, fmt.Errorf("ステータスコード: %d, レスポンス: %s", resp.StatusCode, string(body))
|
||||||
|
}
|
||||||
|
|
||||||
|
return body, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Post はPOSTリクエストを送信
|
||||||
|
func (c *APIClient) Post(endpoint string, data interface{}) ([]byte, error) {
|
||||||
|
url := c.BaseURL + endpoint
|
||||||
|
|
||||||
|
jsonData, err := json.Marshal(data)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("JSONエンコード失敗: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
resp, err := c.HTTPClient.Post(url, "application/json", bytes.NewBuffer(jsonData))
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("POSTリクエスト失敗: %w", err)
|
||||||
|
}
|
||||||
|
defer resp.Body.Close()
|
||||||
|
|
||||||
|
body, err := io.ReadAll(resp.Body)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("レスポンス読み込み失敗: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if resp.StatusCode != http.StatusOK && resp.StatusCode != http.StatusCreated {
|
||||||
|
return nil, fmt.Errorf("ステータスコード: %d, レスポンス: %s", resp.StatusCode, string(body))
|
||||||
|
}
|
||||||
|
|
||||||
|
return body, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Put はPUTリクエストを送信
|
||||||
|
func (c *APIClient) Put(endpoint string, data interface{}) ([]byte, error) {
|
||||||
|
url := c.BaseURL + endpoint
|
||||||
|
|
||||||
|
jsonData, err := json.Marshal(data)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("JSONエンコード失敗: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
req, err := http.NewRequest(http.MethodPut, url, bytes.NewBuffer(jsonData))
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("リクエスト作成失敗: %w", err)
|
||||||
|
}
|
||||||
|
req.Header.Set("Content-Type", "application/json")
|
||||||
|
|
||||||
|
resp, err := c.HTTPClient.Do(req)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("PUTリクエスト失敗: %w", err)
|
||||||
|
}
|
||||||
|
defer resp.Body.Close()
|
||||||
|
|
||||||
|
body, err := io.ReadAll(resp.Body)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("レスポンス読み込み失敗: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if resp.StatusCode != http.StatusOK {
|
||||||
|
return nil, fmt.Errorf("ステータスコード: %d, レスポンス: %s", resp.StatusCode, string(body))
|
||||||
|
}
|
||||||
|
|
||||||
|
return body, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Delete はDELETEリクエストを送信
|
||||||
|
func (c *APIClient) Delete(endpoint string) ([]byte, error) {
|
||||||
|
url := c.BaseURL + endpoint
|
||||||
|
|
||||||
|
req, err := http.NewRequest(http.MethodDelete, url, nil)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("リクエスト作成失敗: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
resp, err := c.HTTPClient.Do(req)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("DELETEリクエスト失敗: %w", err)
|
||||||
|
}
|
||||||
|
defer resp.Body.Close()
|
||||||
|
|
||||||
|
body, err := io.ReadAll(resp.Body)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("レスポンス読み込み失敗: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if resp.StatusCode != http.StatusOK && resp.StatusCode != http.StatusNoContent {
|
||||||
|
return nil, fmt.Errorf("ステータスコード: %d, レスポンス: %s", resp.StatusCode, string(body))
|
||||||
|
}
|
||||||
|
|
||||||
|
return body, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// 使用例
|
||||||
|
func main() {
|
||||||
|
// APIクライアントの作成
|
||||||
|
client := NewAPIClient("https://jsonplaceholder.typicode.com")
|
||||||
|
|
||||||
|
// GETリクエストの例
|
||||||
|
fmt.Println("=== GETリクエスト ===")
|
||||||
|
getData, err := client.Get("/posts/1")
|
||||||
|
if err != nil {
|
||||||
|
fmt.Printf("エラー: %v\n", err)
|
||||||
|
} else {
|
||||||
|
fmt.Printf("レスポンス: %s\n\n", string(getData))
|
||||||
|
}
|
||||||
|
|
||||||
|
// POSTリクエストの例
|
||||||
|
fmt.Println("=== POSTリクエスト ===")
|
||||||
|
postData := map[string]interface{}{
|
||||||
|
"title": "新しい投稿",
|
||||||
|
"body": "これはテスト投稿です",
|
||||||
|
"userId": 1,
|
||||||
|
}
|
||||||
|
postResp, err := client.Post("/posts", postData)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Printf("エラー: %v\n", err)
|
||||||
|
} else {
|
||||||
|
fmt.Printf("レスポンス: %s\n\n", string(postResp))
|
||||||
|
}
|
||||||
|
|
||||||
|
// PUTリクエストの例
|
||||||
|
fmt.Println("=== PUTリクエスト ===")
|
||||||
|
putData := map[string]interface{}{
|
||||||
|
"id": 1,
|
||||||
|
"title": "更新された投稿",
|
||||||
|
"body": "これは更新されたテスト投稿です",
|
||||||
|
"userId": 1,
|
||||||
|
}
|
||||||
|
putResp, err := client.Put("/posts/1", putData)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Printf("エラー: %v\n", err)
|
||||||
|
} else {
|
||||||
|
fmt.Printf("レスポンス: %s\n\n", string(putResp))
|
||||||
|
}
|
||||||
|
|
||||||
|
// DELETEリクエストの例
|
||||||
|
fmt.Println("=== DELETEリクエスト ===")
|
||||||
|
deleteResp, err := client.Delete("/posts/1")
|
||||||
|
if err != nil {
|
||||||
|
fmt.Printf("エラー: %v\n", err)
|
||||||
|
} else {
|
||||||
|
fmt.Printf("レスポンス: %s\n", string(deleteResp))
|
||||||
|
}
|
||||||
|
}
|
||||||
11
examples/hello.go
Normal file
11
examples/hello.go
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
// src/hello.go
|
||||||
|
// A simple Go program that prints "Hello, World!" to the console.
|
||||||
|
// go run src/hello.go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import "fmt"
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
fmt.Println("Hello, World!")
|
||||||
|
}
|
||||||
|
|
||||||
377
readme/coding-conventions.md
Normal file
377
readme/coding-conventions.md
Normal file
@ -0,0 +1,377 @@
|
|||||||
|
# Go コーディング規約
|
||||||
|
|
||||||
|
## 1. 一般的なガイドライン
|
||||||
|
|
||||||
|
1. コードフォーマットは **必ず `gofmt`(または `goimports`)に従う**。手で整形しない。
|
||||||
|
2. インデントは **タブ**(`\t`)を使用する(`gofmt`が自動で設定する)。
|
||||||
|
3. 1行の長さは厳密な制限はないが、**できれば 100 文字前後**を目安にする。
|
||||||
|
4. 1ファイルは 300〜400 行以内を目安とし、長くなりすぎる場合はファイル分割を検討する。
|
||||||
|
5. パッケージ単位で責務を分割し、**小さく・単機能な関数**を心がける。
|
||||||
|
6. エクスポート(大文字始まり)するものは最小限にし、原則として **パッケージ内で完結する API を設計**する。
|
||||||
|
|
||||||
|
## 2. コメント/ドキュメント
|
||||||
|
|
||||||
|
Go では **godoc** 形式のコメントが重要です。
|
||||||
|
|
||||||
|
1. **パッケージコメント**: `package` 宣言の直前に、そのパッケージの説明を書く。
|
||||||
|
|
||||||
|
```go
|
||||||
|
// Package user provides user management functionalities such as
|
||||||
|
// registration, authentication, and profile updates.
|
||||||
|
package user
|
||||||
|
```
|
||||||
|
|
||||||
|
2. **エクスポートされた関数/メソッド**には、**シグネチャ名から始まるコメント**を書く。
|
||||||
|
|
||||||
|
```go
|
||||||
|
// CreateUser creates a new user and stores it into the repository.
|
||||||
|
func CreateUser(name string, age int) (*User, error) {
|
||||||
|
// 実装
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
3. **エクスポートされた型やフィールド**にもコメントを書く。
|
||||||
|
|
||||||
|
```go
|
||||||
|
// User represents a user entity in the system.
|
||||||
|
type User struct {
|
||||||
|
// ID is a unique identifier of the user.
|
||||||
|
ID int64
|
||||||
|
|
||||||
|
// Name is the display name of the user.
|
||||||
|
Name string
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
4. 非エクスポート(小文字始まり)のものでも、複雑な処理や分岐には**行コメント**で意図や前提条件を書いておく。
|
||||||
|
|
||||||
|
```go
|
||||||
|
// cache にヒットした場合は DB に問い合わせない
|
||||||
|
if v, ok := cache[id]; ok {
|
||||||
|
return v, nil
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## 3. 命名規則
|
||||||
|
|
||||||
|
Go は **CamelCase / mixedCaps** を使います(snake_case をあまり使わない)。
|
||||||
|
|
||||||
|
1. **パッケージ名**:
|
||||||
|
|
||||||
|
* すべて小文字、`_` や数字を極力避ける。
|
||||||
|
* 短く意味のある名前にする(`users` より `user` のように単数形が好まれがち)。
|
||||||
|
|
||||||
|
```go
|
||||||
|
package user // 良い例
|
||||||
|
```
|
||||||
|
|
||||||
|
2. **変数・関数名(非エクスポート)**: 先頭小文字の `mixedCaps`。
|
||||||
|
|
||||||
|
```go
|
||||||
|
func loadUser() (*User, error) {
|
||||||
|
userCount := 0
|
||||||
|
_ = userCount
|
||||||
|
// ...
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
3. **エクスポート関数・構造体**: 先頭大文字の `MixedCaps`。
|
||||||
|
|
||||||
|
```go
|
||||||
|
type UserService struct {
|
||||||
|
repo Repository
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewUserService(repo Repository) *UserService {
|
||||||
|
return &UserService{repo: repo}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
4. **定数**:
|
||||||
|
|
||||||
|
* エクスポートする定数は `CamelCase`。
|
||||||
|
* パッケージ内専用であれば先頭小文字。
|
||||||
|
|
||||||
|
```go
|
||||||
|
const DefaultTimeout = 5 * time.Second
|
||||||
|
|
||||||
|
const maxRetryCount = 3
|
||||||
|
```
|
||||||
|
|
||||||
|
5. **レシーバ名**:
|
||||||
|
|
||||||
|
* 型名の1〜2文字の略を使う。
|
||||||
|
* `UserService` → `us`、`Server` → `s` など。
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (s *Server) Start() error {
|
||||||
|
// ...
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## 4. インポート/パッケージ構成
|
||||||
|
|
||||||
|
1. インポートは **自動整形ツール(goimports)にまかせる**。
|
||||||
|
|
||||||
|
2. グループ順は以下が一般的:
|
||||||
|
|
||||||
|
1. 標準ライブラリ
|
||||||
|
2. サードパーティ
|
||||||
|
3. 自プロジェクト内パッケージ
|
||||||
|
|
||||||
|
グループ間は空行で区切る。
|
||||||
|
|
||||||
|
```go
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"fmt"
|
||||||
|
"net/http"
|
||||||
|
|
||||||
|
"github.com/julienschmidt/httprouter"
|
||||||
|
|
||||||
|
"example.com/project/internal/user"
|
||||||
|
"example.com/project/pkg/logger"
|
||||||
|
)
|
||||||
|
```
|
||||||
|
|
||||||
|
3. **循環参照**が起きないようにパッケージを分割する。
|
||||||
|
|
||||||
|
* `cmd/`… エントリポイント(`main` パッケージ)
|
||||||
|
* `internal/`… アプリ内部でのみ使うパッケージ
|
||||||
|
* `pkg/`… 外部にも公開可能なパッケージ
|
||||||
|
|
||||||
|
## 5. エラーハンドリング
|
||||||
|
|
||||||
|
1. Go のエラーは **戻り値の `error`** で扱う。
|
||||||
|
|
||||||
|
```go
|
||||||
|
user, err := repo.FindByID(ctx, id)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("failed to find user: %w", err)
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
2. エラーはできるだけ **早めに return** し、ネストを浅く保つ。
|
||||||
|
|
||||||
|
```go
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
// ここから成功時の処理
|
||||||
|
```
|
||||||
|
|
||||||
|
3. `panic` は **プログラミングミスなど「復旧不能」なケースのみ**で使用し、通常のエラー処理には使わない。
|
||||||
|
|
||||||
|
4. `errors.Is` / `errors.As` を使ってエラー種別を判定する。
|
||||||
|
|
||||||
|
```go
|
||||||
|
if errors.Is(err, sql.ErrNoRows) {
|
||||||
|
// not found の扱い
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## 6. 複数ファイル間の分割時の書き方
|
||||||
|
|
||||||
|
### 6.1 同じパッケージ内での分割
|
||||||
|
|
||||||
|
Go では **同じディレクトリ配下の `.go` ファイルは同じ `package` 名**であれば、1つのパッケージとして扱われます。
|
||||||
|
|
||||||
|
```text
|
||||||
|
user/
|
||||||
|
user.go
|
||||||
|
service.go
|
||||||
|
repository.go
|
||||||
|
```
|
||||||
|
|
||||||
|
すべてのファイルで `package user` と書きます。
|
||||||
|
|
||||||
|
```go
|
||||||
|
// user/user.go
|
||||||
|
package user
|
||||||
|
|
||||||
|
type User struct {
|
||||||
|
ID int64
|
||||||
|
Name string
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
```go
|
||||||
|
// user/service.go
|
||||||
|
package user
|
||||||
|
|
||||||
|
// Service handles user-related usecases.
|
||||||
|
type Service struct {
|
||||||
|
repo Repository
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewService(repo Repository) *Service {
|
||||||
|
return &Service{repo: repo}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
```go
|
||||||
|
// user/repository.go
|
||||||
|
package user
|
||||||
|
|
||||||
|
type Repository interface {
|
||||||
|
FindByID(id int64) (*User, error)
|
||||||
|
Save(user *User) error
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
同一パッケージ内であれば、**インポートなしですべてのシンボルを参照**できます。
|
||||||
|
|
||||||
|
### 6.2 `main` パッケージと内部パッケージの分割
|
||||||
|
|
||||||
|
```text
|
||||||
|
cmd/app/main.go
|
||||||
|
internal/user/service.go
|
||||||
|
internal/user/repository.go
|
||||||
|
```
|
||||||
|
|
||||||
|
```go
|
||||||
|
// cmd/app/main.go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"log"
|
||||||
|
|
||||||
|
"example.com/project/internal/user"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
repo := user.NewInMemoryRepository()
|
||||||
|
svc := user.NewService(repo)
|
||||||
|
|
||||||
|
if err := svc.Run(); err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
```go
|
||||||
|
// internal/user/service.go
|
||||||
|
package user
|
||||||
|
|
||||||
|
type Service struct {
|
||||||
|
repo Repository
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewService(repo Repository) *Service {
|
||||||
|
return &Service{repo: repo}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Service) Run() error {
|
||||||
|
// 実装
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
```go
|
||||||
|
// internal/user/repository.go
|
||||||
|
package user
|
||||||
|
|
||||||
|
type Repository interface {
|
||||||
|
// ...
|
||||||
|
}
|
||||||
|
|
||||||
|
type inMemoryRepository struct {
|
||||||
|
// ...
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewInMemoryRepository() Repository {
|
||||||
|
return &inMemoryRepository{}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
ポイント:
|
||||||
|
|
||||||
|
* **ディレクトリとパッケージ名を一致させる**と分かりやすい。
|
||||||
|
* `cmd/app/` の `main.go` はできるだけ薄くし、構造体やビジネスロジックは `internal/` や `pkg/` に置く。
|
||||||
|
|
||||||
|
### 6.3 テストファイルの分割
|
||||||
|
|
||||||
|
テストコードは基本的に同じパッケージか `package xxx_test` で書きます。
|
||||||
|
|
||||||
|
```go
|
||||||
|
// user/service_test.go
|
||||||
|
package user_test
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"example.com/project/internal/user"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestService_Run(t *testing.T) {
|
||||||
|
repo := user.NewInMemoryRepository()
|
||||||
|
svc := user.NewService(repo)
|
||||||
|
|
||||||
|
if err := svc.Run(); err != nil {
|
||||||
|
t.Fatalf("Run() error = %v", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## 7. gofmt / Lint / VSCode の設定
|
||||||
|
|
||||||
|
### 7.1 フォーマット・リンター
|
||||||
|
|
||||||
|
1. **必須ツール**
|
||||||
|
|
||||||
|
* `gofmt`(標準)
|
||||||
|
* `goimports`(インポートも自動整形)
|
||||||
|
2. **推奨リンター**
|
||||||
|
|
||||||
|
* `golangci-lint`(多数のリンターを統合したツール)
|
||||||
|
|
||||||
|
プロジェクトルートに `.golangci.yml` を置く例:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
run:
|
||||||
|
timeout: 3m
|
||||||
|
tests: true
|
||||||
|
|
||||||
|
linters:
|
||||||
|
enable:
|
||||||
|
- govet
|
||||||
|
- gofmt
|
||||||
|
- gosimple
|
||||||
|
- staticcheck
|
||||||
|
- unused
|
||||||
|
- errcheck
|
||||||
|
|
||||||
|
issues:
|
||||||
|
exclude-use-default: false
|
||||||
|
```
|
||||||
|
|
||||||
|
### 7.2 VSCode の設定例 (`.vscode/settings.json`)
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"go.useLanguageServer": true,
|
||||||
|
"go.formatTool": "goimports",
|
||||||
|
"gopls": {
|
||||||
|
"staticcheck": true
|
||||||
|
},
|
||||||
|
|
||||||
|
"editor.formatOnSave": true,
|
||||||
|
"[go]": {
|
||||||
|
"editor.codeActionsOnSave": {
|
||||||
|
"source.organizeImports": true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
"go.lintTool": "golangci-lint",
|
||||||
|
"go.lintOnSave": "file",
|
||||||
|
"go.lintFlags": [
|
||||||
|
"run",
|
||||||
|
"--fast"
|
||||||
|
],
|
||||||
|
|
||||||
|
"files.trimTrailingWhitespace": true,
|
||||||
|
"files.insertFinalNewline": true
|
||||||
|
}
|
||||||
|
```
|
||||||
Loading…
x
Reference in New Issue
Block a user