2013-05-15 2 views
0

Я работаю над добавлением «шаблонов массива» в проект Go на Github, который называется jsonget. Вот пример того, что я имею в виду массива маска:Ввод в рекурсивный вызов функции golang

> echo "[{product:'coffee', price:2.10}, {product:'beer', price:3.80}]" | jsonget '*.price' 

[2.10, 3.80] 

Код для моей отрасли является here

Проблемы Я бег в с типизацией, когда GetValue встречает * характера, она рекурсивно, вызывая GetValue в подвыражении, но тип всегда возвращается как строка.

Например, в тестовом файле, я даю ему этот кусок: JSON

{ 
     "inventory": [ 
      {"name": "mountain bike", "price": 251.0}, 
      {"name": "red wagon", "price": 90.10}, 
      {"name": "kinesis advantage", "price": 300.0}, 
      {"name": "a ticket to Mars", "price": 1200000000.0} 
     ] 
    } 

Тогда запроса из inventory[*].price, ожидая [251,90.1,300,1.2e+09], но вместо того, чтобы получать ["251","90.1","300","1.2e+09"].

Я хотел бы избежать использования отражения здесь, но я не вижу другого способа сделать это.

+0

Публикация фрагмента кода, выделяющего проблему, была бы полезна. –

+0

Ваша библиотека определена внутри пакета 'main' - вы должны исправить структуру своего проекта. – thwd

ответ

1

Прошу прощения, если я неправильно понял ваш вопрос, но, надеюсь, это поможет.

Я думаю, что вам нужно будет использовать отражение или переключатель типа (http://golang.org/doc/effective_go.html#type_switch, который, вероятно, использует отражение за кулисами, не уверен в этом).

Нельзя слишком сложно изменить существующую функцию valueToString, чтобы включить переключатель типа. Возможно, переименуйте его в convertValue или что-то более общее, и поставьте в него переключатель типа. Если значением является int, возвращаем int, else возвращает строку.

Например:

func convertValue(value interface{}) (text string, i int, err error) { // Was valueToString 
    if value == nil && *printNulls == false { 
     return "", nil, nil 
    } 

    textBytes, err := json.Marshal(value) 
    if err != nil { 
     return "", nil, err 
    } 
    switch value := value.(type) { 
    default: 
     text = string(textBytes) 
     text = quotedString.ReplaceAllString(text, "$1") 
     return text, nil, nil 
    case int: 
     i = textBytes 
     return nil, i, nil 
    } 
} 

Это будет , надеюсьstring() все, за исключением значений, что переключатель типа обнаруживаемых в Интс, которые будут возвращены, как они.

Возможно, это был более чистый способ сделать это, но почти наверняка привлечет большой рефакторинг кода. Основной недостаток заключается в том, что теперь вам нужно проверить, является ли значение нулем перед его использованием.

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

РЕДАКТИРОВАТЬ: Отправляйте сообщение от редакции журнала Andrew Gerrand http://blog.golang.org/2011/01/json-and-go.html, особенно бит около дна об декодировании общих данных. Это должно помочь.

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