- 次のコードを実行できますか?なぜ
動作結果:
パニック:nil mapgoroutine 1のエントリへの割り当て[実行中]:main.main()
上記のように、動作中に例外が発生します。その理由は、辞書Paramのデフォルト値がnilであるためです。キーと値のペアが辞書nilに追加されると、ランタイムエラーパニック:nilマップのエントリへの割り当てが発生します。
正しい変更計画は次のとおりです。
パッケージメイン
「fmt」をインポート
タイプParammap [string] interface {}
タイプShowstruct {
Param
}
func main(){
// 创建Show结构体对象 s := new(Show)
// 为字典Param赋初始值 s.Param = Param{}
// 修改键值对 s.Param["RMB"] = 10000 fmt.Println(s)
}
結果は次のとおりです。
&{map [RMB:10000]}
プロセスは終了コード0で終了しました
- 以下のコードの何が問題になっているのか教えてください
タイプstudentstruct {
Name string
}
func f(v interface {}){
switch msg := v.(type) {
case student, student:
msg.Name
}
}
2つの問題があります:
質問1:interface {}は、メソッドを宣言しないインターフェースです。
質問2:名前は属性であり、メソッドではありません。タイプinterface {}の変数は属性を呼び出すことができません。
- 印刷結果を書き込みます。
タイプPeoplestruct {
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)
}
出力は次のとおりです。
人: {}
結果は次のとおりです。
人々:{11}プロセスは終了コード0で終了しました
- 次のコードには問題があります。理由を説明してください。
パッケージメイン
「fmt」をインポート
タイプPeoplestruct {
Name string
}
func(p People)String()文字列{
return fmt.Sprintf("print: %v", p)
}
func main(){
p := &People{}
p.String()
}
結果は次のとおりです。
ランタイム:ゴルーチンスタックが1000000000バイトの制限を超えています
致命的なエラー:スタックオーバーフロー
ランタイムスタック:
runtime.throw(0x10c122b、0xe)
以下に示すように、%v形式の文字列自体がString()メソッドを呼び出すため、上記のコードにはスタックオーバーフローがあり、上記のスタックオーバーフローは無限の再帰によって発生します。
- 以下のコードで問題を見つけてください。
パッケージメイン
インポート(「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)
}
結果は次のとおりです。
パニック:閉じたchannelokで送信
goroutine 5 [実行中]:
main.main.func1(0xc420098000)
分析:上記のエラーの理由は、チャネルが事前に閉じられているためです。
正しいコードは次のとおりです。
パッケージメイン
インポート(「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には、合計3つのパラメーターがあります。上記の記述は間違っています。正しい記述は次のとおりです。atomic.CompareAndSwapInt32(&value、v、v + delta)
func CompareAndSwapInt32(addr int32、old、new int32)(swapped bool)
最初のパラメーターの値は、操作された値へのポインターである必要があります。この値のタイプはint32です。
後者の2つのパラメーターのタイプは、どちらもint32タイプです。それらの値は、操作された値の古い値と新しい値をそれぞれ表す必要があります
CompareAndSwapInt32・関数は、最初に、パラメーターaddrが指す操作値が、呼び出された後のパラメーターold`の値と等しいかどうかを判別します。
この判断が肯定的である場合にのみ、関数は元の古い値を新しいパラメーターで表される新しい値に置き換えます。それ以外の場合、後続の置換操作は無視されます。
完全なコードは次のとおりです。
パッケージメイン
インポート(「同期/アトミック」「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です。
- 実行後に次のプログラムが爆発するのはなぜですか。
パッケージメイン
インポート(「fmt」「time」)
タイプProjectstruct {}
func(p Project)deferError(){
if err := recover(); err != nil {
fmt.Println("recover: ", err)
}
}