- 下面代码能运行吗?为什么
运行结果:
panic: assignment to entry in nil mapgoroutine 1 [running]:main.main()
如上所示,运行过程中会发生异常,原因是因为字典Param的默认值为nil,当给字典nil增加键值对是就会发生运行时错误panic: assignment to entry in nil map。
正确的修改方案如下:
package main
import “fmt”
type Param map[string]interface{}
type Show struct {
Param
}
func main() {
// 创建Show结构体对象 s := new(Show)
// 为字典Param赋初始值 s.Param = Param{}
// 修改键值对 s.Param["RMB"] = 10000 fmt.Println(s)
}
运行结果如下:
&{map[RMB:10000]}
Process finished with exit code 0
- 请说出下面代码存在什么问题
type student struct {
Name string
}
func f(v interface{}) {
switch msg := v.(type) {
case student, student:
msg.Name
}
}
有两个问题:
问题一:interface{}是一个没有声明任何方法的接口。
问题二:Name是一个属性,而不是方法,interface{}类型的变量无法调用属性。
- 写出打印的结果。
type People struct {
name string json:"name"
}
func main() {
js := {
"name":"11"
}
var p People
err := json.Unmarshal([]byte(js), &p)
if err != nil {
fmt.Println("err: ", err)
return
}
fmt.Println("people: ", p)
}
输出内容如下:
people: {}
运行结果如下:
people: {11}Process finished with exit code 0
- 下面的代码是有问题的,请说明原因。
package main
import “fmt”
type People struct {
Name string
}
func (p People) String() string {
return fmt.Sprintf("print: %v", p)
}
func main() {
p := &People{}
p.String()
}
运行结果如下:
runtime: goroutine stack exceeds 1000000000-byte limit
fatal error: stack overflow
runtime stack:
runtime.throw(0x10c122b, 0xe)
如下所示,上面的代码出现了栈溢出,原因是因为%v格式化字符串是本身会调用String()方法,上面的栈溢出是因为无限递归所致。
- 请找出下面代码的问题所在。
package main
import (“fmt” “time”)
func main() {
ch := make(chan int, 1000)
go func() {
for i := 0; i < 10; i++ {
ch <- i
}
}()
go func() {
for {
a, ok := <-ch
if !ok {
fmt.Println("close")
return }
fmt.Println("a: ", a)
}
}()
close(ch)
fmt.Println("ok")
time.Sleep(time.Second 100)
}
运行结果如下:
panic: send on closed channelok
goroutine 5 [running]:
main.main.func1(0xc420098000)
解析:出现上面错误的原因是因为提前关闭通道所致。
正确代码如下:
package main
import ( “fmt” “time”)
func main() {
// 创建一个缓冲通道
ch := make(chan int, 1000)
go func() {
for i := 0; i < 10; i++ {
ch <- i
}
}()
go func() {
for i := 0; i < 10; i++ {
a, ok := <-ch
if !ok {
fmt.Println("close")
close(ch)
return }
fmt.Println("a: ", a)
}
}()
fmt.Println("ok")
time.Sleep(time.Second)
}
运行结果如下:
ok
a: 0a: 1a: 2a: 3a: 4a: 5a: 6a: 7a: 8a: 9
- 请说明下面代码书写是否正确。
var value int32
func SetValue(delta int32) {
for {
v := value
if atomic.CompareAndSwapInt32(&value, v(v+delta)) {
break
}
}
}
atomic.CompareAndSwapInt32里面一共三个参数,上面的书写错误,正确的书写是:atomic.CompareAndSwapInt32(&value, v,v+delta)
func CompareAndSwapInt32(addr int32, old, new int32) (swapped bool)
第一个参数的值应该是指向被操作值的指针值。该值的类型即为int32。
后两个参数的类型都是int32类型。它们的值应该分别代表被操作值的旧值和新值
CompareAndSwapInt32·函数在被调用之后会先判断参数addr指向的被操作值与参数old`的值是否相等。
仅当此判断得到肯定的结果之后,该函数才会用参数new代表的新值替换掉原先的旧值。否则,后面的替换操作就会被忽略。
完整代码如下:
package main
import ( “sync/atomic” “fmt”)
var value int32
func SetValue(delta int32) {
for {
v := value
// 比较并交换
if atomic.CompareAndSwapInt32(&value, v,v+delta) {
fmt.Println(value)
break
}
}
}
func main() {
SetValue(100)
}
运行结果为100.
- 下面的程序运行后为什么会爆异常。
package main
import ( “fmt” “time”)
type Project struct{}
func (p Project) deferError() {
if err := recover(); err != nil {
fmt.Println("recover: ", err)
}
}