slice
以下代码执行结果
package main
import (
"fmt"
)
func main() {
s := []int{1, 2, 3}
ss := s[1:]
ss = append(ss, 4)
for _, v := range ss {
v += 10
}
for i := range ss {
ss[i] += 10
}
fmt.Println(s) // [1,2,3]
}
短变量声明
Assuming x is declared and y is not declared, which clauses below are correct?
假设声明了x,未声明y,以下哪些句子是正确的?
// 假设声明了x,未声明y,
x, _ := f() // := 短变量声明,要求至少有一个新变量
x, _ = f()
x, y := f()
x, y = f()
func main() {
var x int
// x, _ := f() // := 要求至少有一个新变量
// x, _ = f()
// x, y := f() // 正常声明与定义, y是新的变量
x, y = f() // y 未定义
fmt.Println(x)
fmt.Println(y)
}
nil
执行以下代码时将显示什么?并解释为什么println(InitType()== nil)
无法编译?
type S struct{}
func (s S) F() {}
type IF interface {
F()
}
func InitType() S {
var s S
return s
}
func InitPointer() *S {
var s *S
return s
}
func InitEfaceType() interface{} {
var s S
return s
}
func InitEfacePointer() interface{} {
var s *S
return s
}
func InitIfaceType() IF {
var s S
return s
}
func InitIfacePointer() IF {
var s *S
return s
}
func main() {
println(InitType() == nil) // nil 不能转换为 struct 类型比较
// println(InitPointer() == nil) // true 接口与引用类型(slice、指针、map、chan和函数)指针的零值是 nil
// println(InitEfaceType() == nil) // false
// println(InitEfacePointer() == nil) // false
// println(InitIfaceType() == nil) // false
// println(InitIfacePointer() == nil) //false
}
map
修正以下代码代中
func main() {
// var m map[string]int
// m["a"] = 1
// if v := m["b"]; v != 0 { // v 未找到,默认返回 int零值,无法与nil值比较
// println(v)
// }
m := make(map[string]int)
m["a"] = 1
// if v, ok := m["b"]; ok {
// println(v)
// }
// if v := m["b"]; v == 0 { // v 原始0值, 与零值无法分别
// println(v)
// }
}
pointer
赶写a和b行中的空白,以在咻打印的输出为 foo
type S struct {
m string
}
func f() *S {
return &S{"foo"}
}
func main() {
p := *f()
print(p.m)
}
接口 interface{} pointers
在ABCD中,哪个存在语法问题
type S struct {
}
func f(x interface{}) {}
func g(x *interface{}) {} // 指针接收者
func main() {
s := S{}
p := &s
f(s) //a
g(s) //b
f(p) //c
g(p) //d
/*
λ go run main.go
# command-line-arguments
.\main.go:41:3: cannot use s (type S) as type *interface {} in argument to g:
*interface {} is pointer to interface, not interface
.\main.go:43:3: cannot use p (type *S) as type *interface {} in argument to g:
*interface {} is pointer to interface, not interface
*/
/*
go语言圣经 p123
总结,在合法的方法调用表达式中,只有符合下面三种形式的语句才能成立:
1. 实参接收者和形参接收者是同一个类型,比如都是 T 或者 *T
形参、实参接收都类型相同
2. 实参接收者是 T类型的变量,而形参接收者是 *T类型(编译器会隐式地获取变量的地址)
形参是*T指针接收者时,实参必须是 T类型的变量
3. 实参接收者是 *T类型,而形参接收者是 T类型。(编译器会隐式地解引用接收者,获得实际的取值)
形参是 T类型,实参*T可以编译
/*
}
临时指针 Temporary Pointer
解释为什么下面的打印输出为333, 并修改A行以确保打印出012
const N = 3
func main() {
// m := make(map[int]*int)
// for i := 0; i < N; i++ {
// m[i] = &i
// }
// for _, v := range m {
// print(*v)
// }
// output: 333
m := make(map[int]*int)
for i := 0; i < N; i++ {
v := int(i) // 强制类型转换
m[i] = &v // 取 v的地址
}
fmt.Printf("%v\n", m)
for _, v := range m {
fmt.Println(*v)
}
}
修改下面的代码,退出外部的for循环
func main() {
// for i := 0; i < 3; i++ {
// for j := 0; j < 3; j++ {
// fmt.Println(i, ", ", j, " ")
// break
// }
// }
// fmt.Println()
outer:
for i := 0; i < 3; i++ {
for j := 0; j < 3; j++ {
fmt.Println(i, ", ", j, " ")
break outer
}
}
}
全局变量
要将g声明为全局变量,下面的哪些句子是正确的
var g // 没类型
var g G
var g = G{}
g := G{} // 错, 只能用在func中
延迟函数
修正以下代码中的错误
func main() {
f, err := os.Open("test.txt")
// defer f.Close()
if err != nil {
return
}
defer f.Close()
b, err := ioutil.ReadAll(f)
fmt.Println(string(b))
}
panic堆
以下代码输出什么
func f1() {
defer fmt.Println("f1-begin")
f2()
defer fmt.Println("f1-end")
}
func f2() {
defer fmt.Println("f2-begin")
f3()
defer fmt.Println("f2-end")
}
func f3() {
defer fmt.Println("f3-begin")
panic(0)
defer fmt.Println("f3-end")
}
func main() {
f1()
}
/*
一个defer语句就是一个变通的函数或者方法调用,
函数和参数表达式会在语句执行时求值,
无论正常(return/函数执行完毕),还是不正常(panic), 实际的调用都推迟到包含 defer语句的函数结束后才执行
f3-begin
f2-being
f1-being
panic
*/
recover
如果 defer(recover)
调用时发生宕机,recover可以终止当前的宕机状态,并且返回宕机的值
如果 recover 在其他任何情况下运行,则它没有任何效果且返回nil
执行以下代码时将显示什么?执行以下代码后,退出代码是什么?
func f() {
defer func() {
if r := recover(); r != nil {
log.Printf("recover: %#v", r)
}
}()
panic(1)
panic(2)
}
func main() {
f()
}
/*
D:\projects\gocode\gostudy\demo04 (master -> origin)
λ go run main.go
2019/10/22 20:45:06 recover: 1
*/
type shadowing
type S1 struct {
}
func (s1 S1) f() {
fmt.Println("S1.fn()")
}
func (s1 S1) g() {
fmt.Println("S1.g()")
}
type S2 struct {
S1
}
func (s2 S2) f() {
fmt.Println("S2.fn()")
}
type I interface {
f()
}
func printType(i I) {
fmt.Printf("%T\n", i)
if s1, ok := i.(S1); ok {
s1.f()
s1.g()
}
if s2, ok := i.(S2); ok {
s2.f()
s2.g()
}
}
func main() {
printType(S1{})
printType(S2{})
}
/*
D:\projects\gocode\gostudy\demo04 (master -> origin)
λ go run main.go
main.S1
S1.fn()
S1.g()
main.S2
S2.fn()
S1.g()
*/