2016-01-16 2 views
2

Так что у меня-структуру, как это:Неожиданное значение при получении значения из карты

type Magni struct { 
    ... 
    Handlers map[string]func(*Message) 
    ... 
} 

И у меня есть функция, чтобы создать новый экземпляр структуры:

func New(nick, user, real string) *Magni { 
    return &Magni{ 
     ... 
     Handlers: make(map[string]func(*Message)), 
     ... 
    } 
} 

Но я могу 'получить что-то с карты Handlers с ключом "hey", когда "hey" находится в переменной, он работает только, если я набираю его сам. Вот метод структуры Magni и m является указатель на структуру Magni:

handler := m.Handlers[cmd[3][1:]] // cmd[3][1:] contains string "hey" 
handler2 := m.Handlers["hey"] 

По какой-то причине, значение handler является nil и значение handler2 является 0x401310, в основном я не ожидал handler к be nil.

Я делаю что-то неправильно или это ожидаемое поведение?

ответ

0

Обрезка струны так проблема.

strings.TrimSpace(cmd[3]) 
1

Получение значения на основе значения переменной работы:

m := map[string]string{"hey": "found"} 
fmt.Println(m["hey"]) // found 

cmd := []string{"1", "2", "3", "hey"} 
fmt.Println(m[cmd[3]]) // found 

Он даже работает, если переменная имеет string типа и крути его значение, например:

cmd = []string{"1", "2", "3", "Hhey"} 
fmt.Println(m[cmd[3][1:]]) // found 

Вы выпуск скорее всего, cmd[3] - это string"hey", но если вы нарезаете его как cmd[3][1:], он отрежет первый символ (или, если быть точным: первый байт из его кодирующей последовательности UTF-8, m Эмори представление string с, но персонажи "hey" карты в байтах один-к-одному), так что это будет "ey", для которых вы не найдете каких-либо связанное с ним значение в карте конечно:

cmd = []string{"1", "2", "3", "hey"} 
fmt.Println(m[cmd[3][1:]]) // NOT FOUND (empty string - zero value) 

Try это на Go Playground.

Если cmd[3] - "hey", не нужно нарезать его, просто используйте его в качестве ключа.

Edit: Вы утверждаете cmd[3] содержит string":hey". Если бы, было бы также работать:

cmd = []string{"1", "2", "3", ":hey"} 
fmt.Println(m[cmd[3][1:]]) // found 

Так что ваши cmd[3] не то, что вы думаете. Он может содержать 0 байт или непечатаемые символы. Распечатайте его байты для проверки.Например байты string":hey" являются: [58 104 101 121]

fmt.Println([]byte(":hey")) // Prints [58 104 101 121] 

Распечатайте cmd[3] проверить:

fmt.Println([]byte(cmd[3])) 

Вы также мог бы сравнить его с strings вы думаете, что это, но это будет только сказать, является ли они равны (и не сообщают вам, где разница):

fmt.Println(cmd[3] == ":hey", cmd[3][1:] == "hey") 
+0

Фактически 'cmd [3]' это строка ': hey' so' cmd [3] [1:] 'is' hey'. –

+0

@StianOK Тогда ваш 'cmd [3]' не является 'string'': "hey". См. Редактирование, чтобы проверить его. – icza

Смежные вопросы