Использование указателей в качестве ключа карты, неспособность увидеть, установлен ключ или нет - PullRequest
0 голосов
/ 09 октября 2019

У меня есть следующая карта: (MyStruct1 и MyStruct2 - очень большие сложные структуры)

faults := make(map[*MyStruct1][]MyStruct2)

У меня есть цикл for, который перебирает фрагмент, и первая проверка состоит в том, чтобы увидеть, существует ли объект вкарта:

for _, device := range devices {
    for _, drive := range device.Drives {
        if !strings.EqualFold(drive.Status, "ONLINE") {
            // Check if this is the first fault for this device
            if _, set := faults[&device]; !set {
                // other stuff snipped for brevity
                faults[&device] = make([]MyStruct2, 0)
            }
            faults[&device] = append(faults[&device], drive)
        }
    }
}

Эта проверка, кажется, работает для первой итерации, но затем эта проверка не выполняется для каждого последующего устройства в итерации. Когда он переходит к следующему устройству, адрес другой и, следовательно, новый ключ для карты ... почему он не проходит эту проверку?

            if _, set := foo[&device]; !set {
                // other stuff snipped for brevity
                faults[devicePtr] = make([]MyStruct2, 0)
            }

Я также попытался выполнить проверку следующим образом:

if foo[&device] == nil {
    // other stuff snipped for brevity
    faults[devicePtr] = make([]MyStruct2, 0)
}

* edit * На самом деле все оказалось простым исправлением.

for i, device := range devices {
    devicePtr := &devices[i]
    for _, drive := range device.Drives {

Затем используйте devicePtr в качестве ключа моей карты.

Спасибо за помощь.

1 Ответ

0 голосов
/ 10 октября 2019

Во-первых, я предпочитаю использовать другой идентификатор в качестве ключа карты. В этом примере я использую device.ID в качестве ключа карты

package main

import (
    "fmt"
    "strings"
)

type Device struct {
    ID     int64
    Drives []Drive
}

type Drive struct {
    Name   string
    Status string
}

func main() {
    devices := []Device{
        {
            ID: 1,
            Drives: []Drive{
                {
                    Name:   "Drive1.1",
                    Status: "ONLINE",
                },
                {
                    Name:   "Drive1.2",
                    Status: "OFFLINE",
                },
            },
        },
        {
            ID: 2,
            Drives: []Drive{
                {
                    Name:   "Drive2.1",
                    Status: "OFFLINE",
                },
                {
                    Name:   "Drive2.2",
                    Status: "OFFLINE",
                },
            },
        },
        {
            ID: 3,
            Drives: []Drive{
                {
                    Name:   "Drive3.1",
                    Status: "OFFLINE",
                },
                {
                    Name:   "Drive3.2",
                    Status: "ONLINE",
                },
            },
        },
    }

    faults := make(map[int64][]Drive)

    for _, device := range devices {
        for _, drive := range device.Drives {
            if !strings.EqualFold(drive.Status, "ONLINE") {
                // Check if this is the first fault for this device
                if _, set := faults[device.ID]; !set {
                    // other stuff snipped for brevity
                    faults[device.ID] = make([]Drive, 0)
                }
                faults[device.ID] = append(faults[device.ID], drive)
            }
        }
    }

    fmt.Printf("%+v", faults)
}

При использовании этого подхода есть некоторые преимущества:

  1. Более быстрое считывание карты
  2. Подробнеечитаемый код

Но, если вы по-прежнему предпочитаете использовать указатель в качестве ключа карты, вы должны получить доступ к срезу. Цикл будет таким:

faults := make(map[*Device][]Drive)

for i := range devices {
    for _, drive := range devices[i].Drives {
        if !strings.EqualFold(drive.Status, "ONLINE") {
            // Check if this is the first fault for this device
            if _, set := faults[&devices[i]]; !set {
                // other stuff snipped for brevity
                faults[&devices[i]] = make([]Drive, 0)
            }
            faults[&devices[i]] = append(faults[&devices[i]], drive)
        }
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...