使用VScode开发Go的奇妙体验-part1

前面我写了一篇关于实现一个像PHP风格一样的Go语言map/array/slice解析的文章,在写这篇文章的过程中我还发现了一些有意思的事情,这里记录两件。

判断一个变量的类型

比如一个变量structure的类型可能是map[string]any或者是[]any,正常我们的想法肯定是

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
package mai

import "fmt"

func main() {
	var structure any

	switch structure.(type) {
	case map[string]any:
		s := structure.(map[string]any)
		fmt.Printf("%v", s)
	case []any:
		s := structure.([]any)
		fmt.Printf("%v", s)
	}
}

我当时写完这段代码的第一反应就是为什么还要在里面再转换一次呢?外面都已经判断过是这样的了,肯定里面要按判断的这个类型去用啊,不过也没有多想,这个时候看到了VSCode有提示

Go-staticcheck警告

这个意思就是可以改写成

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
package main

import "fmt"

func main() {
	var structure any

	switch structure := structure.(type) {
	case map[string]any:
		fmt.Printf("%v", structure)
	case []any:
		fmt.Printf("%v", structure)
	}
}

这个写法简直完美了,简洁又优雅,虽然感觉有点奇怪。具体的解释可以看Go语言的类型选择

补充:刚才验证了下,如果想直接获取一个变量的类型,正常的做法是reflect.TypeOf(structure),而不是structure.(type),后者就是只能在switch/case语句中使用的,所以它就是这么一个结构,无论如何,这确实是一个非常好的设计。

使用VSCode粘贴json内容时自动生成structs

在写Garray的过程中,我发现把那段用于测试的json粘贴到Go的代码中时,它会自动转换成struct,而且是会将整个json中用到的所有struct都能定义出来,刚开始我还以为是我复制错了,直到反复确认才确定了确实是VSCode的功能,至于是哪个插件做到的我就不知道了。比如粘贴这样一段json到*.go的代码中时,粘贴进去的将是这样的一组类型定义。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
{
  "name": "John Doe",
  "age": 30,
  "email": "john.doe@example.com",
  "isActive": true,
  "address": {
   "street": "123 Main St",
   "city": "Anytown",
   "state": "CA",
   "postalCode": "12345"
  },
  "phoneNumbers": [
   {
    "type": "home",
    "number": "555-555-5555"
   },
   {
    "type": "work",
    "number": "555-555-5556"
   }
  ],
  "projects": [
   {
    "name": "Project Alpha",
    "status": "completed",
    "tasks": [
     {
      "name": "Task 1",
      "dueDate": "2023-10-01",
      "completed": true
     },
     {
      "name": "Task 2",
      "dueDate": "2023-10-15",
      "completed": false
     }
    ]
   },
   {
    "name": "Project Beta",
    "status": "in progress",
    "tasks": [
     {
      "name": "Task 3",
      "dueDate": "2023-11-01",
      "completed": false
     },
     {
      "name": "Task 4",
      "dueDate": "2023-12-01",
      "completed": false
     }
    ]
   }
  ],
  "preferences": {
   "contactMethod": "email",
   "newsletterSubscribed": true,
   "languages": ["English", "Spanish", "German"]
  }
 }
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
type AutoGenerated struct {
	Name string `json:"name"`
	Age int `json:"age"`
	Email string `json:"email"`
	IsActive bool `json:"isActive"`
	Address Address `json:"address"`
	PhoneNumbers []PhoneNumbers `json:"phoneNumbers"`
	Projects []Projects `json:"projects"`
	Preferences Preferences `json:"preferences"`
}
type Address struct {
	Street string `json:"street"`
	City string `json:"city"`
	State string `json:"state"`
	PostalCode string `json:"postalCode"`
}
type PhoneNumbers struct {
	Type string `json:"type"`
	Number string `json:"number"`
}
type Tasks struct {
	Name string `json:"name"`
	DueDate string `json:"dueDate"`
	Completed bool `json:"completed"`
}
type Projects struct {
	Name string `json:"name"`
	Status string `json:"status"`
	Tasks []Tasks `json:"tasks"`
}
type Preferences struct {
	ContactMethod string `json:"contactMethod"`
	NewsletterSubscribed bool `json:"newsletterSubscribed"`
	Languages []string `json:"languages"`
}

这简直太妙了。

Licensed under CC BY-NC-SA 4.0
Built with Hugo
Theme Stack designed by Jimmy