จะล้างแผนที่ใน Go ได้อย่างไร?


86

ฉันกำลังมองหาบางสิ่งบางอย่างเช่น C ++ ฟังก์ชั่นสำหรับชนิดดั้งเดิม.clear() map

หรือฉันควรสร้างแผนที่ใหม่แทน?

Update: ขอบคุณสำหรับคำตอบ จากการดูคำตอบฉันเพิ่งตระหนักว่าบางครั้งการสร้างแผนที่ใหม่อาจทำให้เกิดความไม่สอดคล้องกันบางอย่างที่เราไม่ต้องการ พิจารณาตัวอย่างต่อไปนี้:

var a map[string]string
var b map[string]string

func main() {
    a = make(map[string]string)
    b=a
    a["hello"]="world"
    a = nil
    fmt.Println(b["hello"])
}

ฉันหมายความว่าสิ่งนี้ยังคงแตกต่างจาก.clear()ฟังก์ชันใน c ++ ซึ่งจะล้างเนื้อหาในวัตถุ


1
ดูการสนทนานี้ได้ที่groups.google.com/d/topic/golang-nuts/6yHDC7IYCj4/discussion
perreal

1
นอกจากนี้ยังมีการอภิปรายเกี่ยวกับการล้างข้อมูลในตัว
perreal

คำตอบ:


110

คุณควรสร้างแผนที่ใหม่ ไม่มีเหตุผลที่แท้จริงที่จะต้องกังวลในการพยายามล้างข้อมูลที่มีอยู่เว้นแต่จะมีการอ้างถึงแผนที่เดียวกันด้วยโค้ดหลายชิ้นและชิ้นเดียวจำเป็นต้องล้างค่าอย่างชัดเจนเพื่อให้โค้ดอื่น ๆ มองเห็นการเปลี่ยนแปลงนี้

ใช่คุณควรจะพูด

mymap = make(map[keytype]valtype)

หากคุณจำเป็นต้องล้างแผนที่ที่มีอยู่ไม่ว่าจะด้วยเหตุผลใดก็ทำได้ง่ายพอ:

for k := range m {
    delete(m, k)
}

1
ดังนั้นการลบองค์ประกอบทีละรายการเป็นวิธีเดียวที่จะทำได้?
lavin

@lavin: ใช่. ไม่มีฟังก์ชันในตัวให้ทำเช่นนี้และคุณไม่สามารถมีฟังก์ชันไลบรารีที่ทำสิ่งนี้สำหรับแผนที่โดยพลการ แต่มันก็แค่ 3 บรรทัดอยู่ดี
Lily Ballard

6
การแก้ไขเนื้อหาของแผนที่ในขณะที่ทำซ้ำตามค่าทั้งหมดเป็นเรื่องปกติหรือไม่ ภาษาอื่นจะทำงานไม่ถูกต้องกับสิ่งนี้
John Jeffery

5
@JohnJeffery: ฉันทดสอบสิ่งนี้ก่อนที่จะโพสต์ ดูเหมือนจะได้ผล ภาษาจริงจากข้อมูลจำเพาะระบุว่าThe iteration order over maps is not specified and is not guaranteed to be the same from one iteration to the next. If map entries that have not yet been reached are deleted during iteration, the corresponding iteration values will not be produced. If map entries are inserted during iteration, the behavior is implementation-dependent, but the iteration values for each entry will be produced at most once. If the map is nil, the number of iterations is 0.สิ่งนี้ได้รับการสนับสนุน
Lily Ballard

18
เริ่มจาก Go 1.11 การดำเนินการล้างแผนที่ของแบบฟอร์มนี้ได้รับการปรับให้เหมาะสมโดยคอมไพเลอร์ github.com/golang/go/blob/master/doc/go1.11.html
Benjamin B.

21

แตกต่างจากภาษา C ++ Go เป็นภาษาที่รวบรวมขยะ คุณต้องคิดสิ่งต่างออกไปเล็กน้อย

เมื่อคุณสร้างแผนที่ใหม่

a := map[string]string{"hello": "world"}
a = make(map[string]string)

แผนที่เดิมจะถูกเก็บขยะในที่สุด คุณไม่จำเป็นต้องล้างด้วยตนเอง แต่จำไว้ว่าแผนที่ (และชิ้นส่วน) เป็นประเภทอ้างอิง make()คุณสร้างพวกเขาด้วย แผนที่ต้นแบบจะถูกเก็บรวบรวมขยะก็ต่อเมื่อไม่มีการอ้างอิงถึง ดังนั้นเมื่อคุณทำ

a := map[string]string{"hello": "world"}
b := a
a = make(map[string]string)

อาร์เรย์เดิมจะไม่ถูกเก็บรวบรวม (จนกว่า b จะถูกเก็บรวบรวมขยะหรือ b หมายถึงอย่างอื่น)



-5

หากคุณกำลังพยายามทำสิ่งนี้แบบวนซ้ำคุณสามารถใช้ประโยชน์จากการเริ่มต้นเพื่อล้างแผนที่ให้คุณได้ ตัวอย่างเช่น:

for i:=0; i<2; i++ {
    animalNames := make(map[string]string)
    switch i {
        case 0:
            animalNames["cat"] = "Patches"
        case 1:
            animalNames["dog"] = "Spot";
    }

    fmt.Println("For map instance", i)
    for key, value := range animalNames {
        fmt.Println(key, value)
    }
    fmt.Println("-----------\n")
}

เมื่อคุณดำเนินการสิ่งนี้จะเป็นการล้างแผนที่ก่อนหน้าและเริ่มต้นด้วยแผนที่ว่างเปล่า สิ่งนี้ได้รับการตรวจสอบโดยผลลัพธ์:

$ go run maptests.go 
For map instance 0
cat Patches
-----------

For map instance 1
dog Spot
-----------

3
นั่นไม่ใช่การล้างแผนที่ แต่สร้างแผนที่ใหม่และเชื่อมโยงกับตัวแปรท้องถิ่นที่มีชื่อเดียวกันในแต่ละวง
Delaney
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.