2016-12-24 4 views
0

Я учусь идти Ланг и я наткнулся ниже кодинициализации переменной и область действия в Golang

var kvstore = make(map[string][]byte) 

// this function instantiates the database 
func init_db() { 
    kvstore = make(map[string][]byte) 
} 

// put inserts a new key value pair or updates the value for a 
// given key in the store 
func put(key string, value []byte) { 
    kvstore[key] = value 
} 

// get fetches the value associated with the key 
func get(key string) []byte { 
    v, _ := kvstore[key] 
    return v 
} 

У меня 2 сомнения:

  1. почему это необходимо инициализировать kvstore переменную один раз в глобальном масштабе и затем один раз в init_db функция?

  2. Когда кто-то звонит put/get функция из другого модуля, как поддерживается состояние kvstore? (В «C», мы, как правило, явно передать структуру данных в функции, но в этом случае поставить или получить непосредственно работает на глобальной переменной kvstore)

+0

Вы можете повторно инициализировать с помощью 'init_db()' – e0k

+0

Невозможно вызвать get/put из других модулей, потому что эти символы не экспортируются. Первая буква должна быть в верхнем регистре для экспортируемого символа/идентификатора. Kvstore определяется как глобальная переменная, но поскольку первая буква не является прописной, она не видна напрямую и недоступна из внешних модулей. Это похоже на статическую переменную в C. – chmike

ответ

0

Там нет необходимости инициализировать kvstore дважды.

Вы можете представить глобальную переменную kvstore как нечто похожее на переменную со статической продолжительностью в C. И небезопасно обращаться к карте одновременно с записью. Возможно, вам потребуется синхронизировать, подобно доступу к статической глобальной переменной в C.

+1

Это не совсем точно. Текущая реализация позволяет безопасно использовать put/get без вызова init_db. init_db можно использовать для очистки db. Желательно ли другое, но двойная инициализация не эквивалентна единственному init. – pvg

+0

@pvg Хорошая точка. Я думаю, что 'init_db' следует переименовать в' clear_db', потому что всякий раз, когда вы вызываете функцию, она всегда просто ** очищает db **. И 'init_db' звучит как функция, которая должна вызываться перед использованием некоторой библиотеки/модуля. – cshu

+1

Кажется, что это код скелета/стартера из класса распределенных систем CMU. Так что, вероятно, не изменится или не подумает слишком много глубоких мыслей о его дизайне! https://github.com/CMU-440-F16/p0 – pvg

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