一道挺有意思的题

package main

import (
    "encoding/json"
    "fmt"
)

type AutoGenerated struct {
    Age   int    `json:"age"`
    Name  string `json:"name"`
    Child []int  `json:"child"`
}

func main() {
    jsonStr1 := `{"age": 14,"name": "potter", "child":[1,2,3]}`
    a := AutoGenerated{}
    json.Unmarshal([]byte(jsonStr1), &a)
    aa := a.Child
    fmt.Println(aa)
    jsonStr2 := `{"age": 12,"name": "potter", "child":[3,4,5,7,8,9]}`
    json.Unmarshal([]byte(jsonStr2), &a)
    fmt.Println(aa)
}

选项:
A:[1 2 3] [1 2 3]
B:[1 2 3] [3 4 5]
C:[1 2 3] [3 4 5 6 7 8 9]
D:[1 2 3] [3 4 5 0 0 0]

应该选哪个呢?为什么?

zjx
讨论数量: 9
qiaoshuai_job

选择 B :+1:

1年前 评论

选择 B,....因为:.一楼说的

1年前 评论

第二次解析时,a.Child已经不是一个空切片了,而是一个len为3,cap容量为3的[1,2,3]切片了。所以

file

1年前 评论
uptutu 1年前

@夜幕下的风之 感觉你理解错了

1年前 评论
夜幕下的风之 1年前

你们是怎么理解的,我是真的没看懂

1年前 评论

切片保存了对底层数组的引用,若你将某个切片赋予另一个切片,它们会引用同一个数组。(来自数据《高效的 Go 编程 Effective Go》 )。a.Child和aa引用的是同一个底层数组,而第二次解码json字符串的时候改变了a.Child指向的底层数组和长度容量,但aa的长度容量没有改变

1年前 评论

@ieso 嗯,第二次解码之后,意味着a.Child 和 aa 指向了不同的底层数组是吧

1年前 评论
ieso 1年前

file

file

@ieso 你看下这个,我看第二次解析之后数组是有两个了

1年前 评论

@returnfalse 我之前理解的确实有些偏差。你如果把第二个json中的数组部分长度改成和第一个json中的数组一样或者更小,你会发现这两个切片的底层数组还是同一个指针。所以真相只有一个:解析json、改变底层数组的时候,确实改变了原来的底层数组;但是如果容量不够,在改变了原来的底层数组的同时,会分配一块新的内存建立新的底层数组的。

1年前 评论

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!