Изменение значений структуры, переданной по ссылке

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

ОДНАКО, хотя код выполняется, а значения идентифицируются и преобразуются внутри функции, когда элемент управления возвращается к функции main (), структура не имеет значений, которые я хотел бы сохранить там.

Вот код:

package main

import (
    "fmt"
    "reflect"
    "strconv"
)

type x struct {
    f1 string
    f2 int
    f3 bool
}

func main() {
    s := x{}
    getData(&s.f1, "AAA")
    getData(&s.f2, "1")
    getData(&s.f3, "true")
    fmt.Println(s)

}
func getData(data interface{}, value string) {
    if value != "" {
        switch reflect.TypeOf(data).String() {
        case "*int":
            data, _ = strconv.Atoi(value)
        case "*bool":
            data, _ = strconv.ParseBool(value)
        case "*string":
            data = value
        }
    }
}

В этом примере я получаю { 0 false}, ожидая { AAA 1 true}.

Есть ли какой-нибудь Golang GURU, который может сказать мне, что я делаю не так с этим кодом?

Ниже ссылка на детскую площадку https://play.golang.org/p/l1_INJLOhAq

Перестаньте думать об указателе как о «ссылке». Это не так и бесполезно рассматривать указатель как ссылку. (Что бы вы назвали *** int?)

Volker 27.10.2018 18:21

Спасибо, что НЕ помогали @Volker. Хотя ваша точка зрения в какой-то мере верна, люди, которые действительно знают эту вещь, поняли ее с первого раза и мудро потратили свое время на то, чтобы помочь, а не критиковать. Измени свое отношение, товарищ, если не хочешь помочь, передавай ...

TTKDroid 07.11.2018 07:27
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
2
261
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Вам нужно использовать reflect.Value.Elem(), чтобы получить фактическое значение, а не сам указатель.

Вот краткая суть:

func getData(data interface{}, value string) {

    switch v := data.(type) {
    case *int:
        val := reflect.ValueOf(v).Elem()
        intVal, _ := strconv.Atoi(value)
        val.SetInt(int64(intVal))
    }
}

Предлагаю прочитать Законы отражения

Я предлагаю ответ @ ThunderCat, который проще и лучше подходит для вашего варианта использования. В размышлениях действительно нет нужды.

ssemilla 27.10.2018 08:24

Спасибо weavr. Ваше решение также работает, но действительно то, что опубликовано ThundeCat, мне больше подходит. Спасибо друг

TTKDroid 27.10.2018 08:36
Ответ принят как подходящий

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

func getData(data interface{}, value string) {
    if value != "" {
        switch data := data.(type) {
        case *int:
            *data, _ = strconv.Atoi(value)
        case *bool:
            *data, _ = strconv.ParseBool(value)
        case *string:
            *data = value
        }
    }
}

Подробнее о переключателях типа: Go Tour, Go Спецификация, Эффективный Go.

Спасибо ThunderCat! Переключатель типа был отсутствующим звеном и причиной, по которой я получал «недопустимый косвенный источник данных (тип интерфейса {})». Спасибо, что поделился

TTKDroid 27.10.2018 08:32

Другие вопросы по теме