Adakah terdapat cara yang baik untuk menjadikan jenis angka sesuai untuk 'kaedah.Panggilan' dalam golang?

WBOY
Lepaskan: 2024-02-08 23:06:08
ke hadapan
1182 orang telah melayarinya

Adakah terdapat cara yang baik untuk menjadikan jenis angka sesuai untuk kaedah.Panggilan dalam golang?

PHP editor Youzi Dalam golang, apabila menggunakan kaedah.Kaedah panggilan untuk memanggil fungsi, anda mungkin menghadapi beberapa masalah dengan parameter jenis angka. Walau bagaimanapun, terdapat beberapa cara untuk menyelesaikan masalah ini. Pertama, kita boleh menukar jenis angka kepada mencerminkan yang sepadan. Jenis nilai sebelum menghantarnya kepada kaedah. Kaedah panggilan. Di samping itu, kita juga boleh menggunakan kaedah pantulan untuk mendapatkan jenis parameter fungsi dan melaksanakan pemprosesan yang sepadan mengikut jenis parameter. Ringkasnya, melalui kaedah ini, kita boleh menjadikan jenis berangka sesuai untuk penggunaan kaedah. Kaedah panggilan dalam golang, dengan itu menyelesaikan masalah ini.

Kandungan soalan

Taman Permainan Code Go:

package main

import (
    "fmt"
    "reflect"
)

func (s StructWithManyMethods) Func1(a int, b uint, c float64) {
    fmt.Printf("func:Func1 a:%d b:%d c:%f \n", a, b, c)
}
func (s StructWithManyMethods) Func2(a string, b int, c int, d int) {
    fmt.Printf("func:Func2 a:%s b:%d c:%d d:%d\n", a, b, c, d)
}

type StructWithManyMethods struct {
}

func (s StructWithManyMethods) CallMethod(n string, p []interface{}) {
    method := reflect.ValueOf(s).MethodByName(n)
    methodType := method.Type()
    for i := 0; i < methodType.NumIn(); i++ {
        in := methodType.In(i)
        switch in.Kind() {
        case reflect.Float32:
            switch v := p[i].(type) {
            case float64:
                p[i] = float32(v)
            case float32:
                p[i] = float32(v)
            case int:
                p[i] = float32(v)
            case uint:
                p[i] = float32(v)
            case int8:
                p[i] = float32(v)
            case uint8:
                p[i] = float32(v)
            case int16:
                p[i] = float32(v)
            case uint16:
                p[i] = float32(v)
            case int32:
                p[i] = float32(v)
            case uint32:
                p[i] = float32(v)
            case int64:
                p[i] = float32(v)
            case uint64:
                p[i] = float32(v)
            }
        case reflect.Float64:
            switch v := p[i].(type) {
            case float64:
                p[i] = float64(v)
            case float32:
                p[i] = float64(v)
            case int:
                p[i] = float64(v)
            case uint:
                p[i] = float64(v)
            case int8:
                p[i] = float64(v)
            case uint8:
                p[i] = float64(v)
            case int16:
                p[i] = float64(v)
            case uint16:
                p[i] = float64(v)
            case int32:
                p[i] = float64(v)
            case uint32:
                p[i] = float64(v)
            case int64:
                p[i] = float64(v)
            case uint64:
                p[i] = float64(v)
            }
        case reflect.Int:
            switch v := p[i].(type) {
            case float64:
                p[i] = int(v)
            case float32:
                p[i] = int(v)
            case int:
                p[i] = int(v)
            case uint:
                p[i] = int(v)
            case int8:
                p[i] = int(v)
            case uint8:
                p[i] = int(v)
            case int16:
                p[i] = int(v)
            case uint16:
                p[i] = int(v)
            case int32:
                p[i] = int(v)
            case uint32:
                p[i] = int(v)
            case int64:
                p[i] = int(v)
            case uint64:
                p[i] = int(v)
            }
        case reflect.Uint:
            switch v := p[i].(type) {
            case float64:
                p[i] = uint(v)
            case float32:
                p[i] = uint(v)
            case int:
                p[i] = uint(v)
            case uint:
                p[i] = uint(v)
            case int8:
                p[i] = uint(v)
            case uint8:
                p[i] = uint(v)
            case int16:
                p[i] = uint(v)
            case uint16:
                p[i] = uint(v)
            case int32:
                p[i] = uint(v)
            case uint32:
                p[i] = uint(v)
            case int64:
                p[i] = uint(v)
            case uint64:
                p[i] = uint(v)
            }
        case reflect.Int8:
            switch v := p[i].(type) {
            case float64:
                p[i] = int8(v)
            case float32:
                p[i] = int8(v)
            case int:
                p[i] = int8(v)
            case uint:
                p[i] = int8(v)
            case int8:
                p[i] = int8(v)
            case uint8:
                p[i] = int8(v)
            case int16:
                p[i] = int8(v)
            case uint16:
                p[i] = int8(v)
            case int32:
                p[i] = int8(v)
            case uint32:
                p[i] = int8(v)
            case int64:
                p[i] = int8(v)
            case uint64:
                p[i] = int8(v)
            }
        case reflect.Uint8:
            switch v := p[i].(type) {
            case float64:
                p[i] = uint8(v)
            case float32:
                p[i] = uint8(v)
            case int:
                p[i] = uint8(v)
            case uint:
                p[i] = uint8(v)
            case int8:
                p[i] = uint8(v)
            case uint8:
                p[i] = uint8(v)
            case int16:
                p[i] = uint8(v)
            case uint16:
                p[i] = uint8(v)
            case int32:
                p[i] = uint8(v)
            case uint32:
                p[i] = uint8(v)
            case int64:
                p[i] = uint8(v)
            case uint64:
                p[i] = uint8(v)
            }
        case reflect.Int16:
            switch v := p[i].(type) {
            case float64:
                p[i] = int16(v)
            case float32:
                p[i] = int16(v)
            case int:
                p[i] = int16(v)
            case uint:
                p[i] = int16(v)
            case int8:
                p[i] = int16(v)
            case uint8:
                p[i] = int16(v)
            case int16:
                p[i] = int16(v)
            case uint16:
                p[i] = int16(v)
            case int32:
                p[i] = int16(v)
            case uint32:
                p[i] = int16(v)
            case int64:
                p[i] = int16(v)
            case uint64:
                p[i] = int16(v)
            }
        case reflect.Uint16:
            switch v := p[i].(type) {
            case float64:
                p[i] = uint16(v)
            case float32:
                p[i] = uint16(v)
            case int:
                p[i] = uint16(v)
            case uint:
                p[i] = uint16(v)
            case int8:
                p[i] = uint16(v)
            case uint8:
                p[i] = uint16(v)
            case int16:
                p[i] = uint16(v)
            case uint16:
                p[i] = uint16(v)
            case int32:
                p[i] = uint16(v)
            case uint32:
                p[i] = uint16(v)
            case int64:
                p[i] = uint16(v)
            case uint64:
                p[i] = uint16(v)
            }
        case reflect.Int32:
            switch v := p[i].(type) {
            case float64:
                p[i] = int32(v)
            case float32:
                p[i] = int32(v)
            case int:
                p[i] = int32(v)
            case uint:
                p[i] = int32(v)
            case int8:
                p[i] = int32(v)
            case uint8:
                p[i] = int32(v)
            case int16:
                p[i] = int32(v)
            case uint16:
                p[i] = int32(v)
            case int32:
                p[i] = int32(v)
            case uint32:
                p[i] = int32(v)
            case int64:
                p[i] = int32(v)
            case uint64:
                p[i] = int32(v)
            }
        case reflect.Uint32:
            switch v := p[i].(type) {
            case float64:
                p[i] = uint32(v)
            case float32:
                p[i] = uint32(v)
            case int:
                p[i] = uint32(v)
            case uint:
                p[i] = uint32(v)
            case int8:
                p[i] = uint32(v)
            case uint8:
                p[i] = uint32(v)
            case int16:
                p[i] = uint32(v)
            case uint16:
                p[i] = uint32(v)
            case int32:
                p[i] = uint32(v)
            case uint32:
                p[i] = uint32(v)
            case int64:
                p[i] = uint32(v)
            case uint64:
                p[i] = uint32(v)
            }
        case reflect.Int64:
            switch v := p[i].(type) {
            case float64:
                p[i] = int64(v)
            case float32:
                p[i] = int64(v)
            case int:
                p[i] = int64(v)
            case uint:
                p[i] = int64(v)
            case int8:
                p[i] = int64(v)
            case uint8:
                p[i] = int64(v)
            case int16:
                p[i] = int64(v)
            case uint16:
                p[i] = int64(v)
            case int32:
                p[i] = int64(v)
            case uint32:
                p[i] = int64(v)
            case int64:
                p[i] = int64(v)
            case uint64:
                p[i] = int64(v)
            }
        case reflect.Uint64:
            switch v := p[i].(type) {
            case float64:
                p[i] = uint64(v)
            case float32:
                p[i] = uint64(v)
            case int:
                p[i] = uint64(v)
            case uint:
                p[i] = uint64(v)
            case int8:
                p[i] = uint64(v)
            case uint8:
                p[i] = uint64(v)
            case int16:
                p[i] = uint64(v)
            case uint16:
                p[i] = uint64(v)
            case int32:
                p[i] = uint64(v)
            case uint32:
                p[i] = uint64(v)
            case int64:
                p[i] = uint64(v)
            case uint64:
                p[i] = uint64(v)
            }
        }
    }
    parameterValues := make([]reflect.Value, 0)
    for _, e := range p {
        parameterValues = append(parameterValues, reflect.ValueOf(e))
    }
    method.Call(parameterValues)
}

func main() {
    var s StructWithManyMethods
    s.CallMethod("Func1", []interface{}{1.0, 2.0, 3})
    s.CallMethod("Func2", []interface{}{"test", 1, 2, 3.0})
}
Salin selepas log masuk

Keluaran:

func:Func1 a:1 b:2 c:3.000000 
func:Func2 a:test b:1 c:2 d:3
Salin selepas log masuk

Kerana saya perlu memanggil kaedah secara dinamik, tetapi parameter datang dari format data yang berbeza, yang membawa kepada keperluan untuk menukar jenis berangka. Sebagai contoh, apabila menghuraikan JSON dalam Golang, jenis nombor yang tidak ditentukan dianggap sebagai float64, walaupun ia mungkin harus menjadi int.

Kod itu kelihatan buruk tetapi berfungsi dengan baik.

Saya tertanya-tanya jika ada cara yang lebih baik untuk melakukan ini.

Penyelesaian

Gunakan cerminkan API untuk menukar nilai.

func (s StructWithManyMethods) CallMethod(n string, p []interface{}) error {
    method := reflect.ValueOf(s).MethodByName(n)
    methodType := method.Type()
    parameterValues := make([]reflect.Value, methodType.NumIn())
    if len(p) < len(parameterValues) {
        return fmt.Errorf("expected %d parameters, got %d", len(parameterValues), len(p))
    }
    for i := range parameterValues {
        in := methodType.In(i)
        v := reflect.ValueOf(p[i])
        if !v.CanConvert(in) {
            return fmt.Errorf("cannot convert p[%d] from %s to %s", i, v.Type(), in)
        }
        parameterValues[i] = reflect.ValueOf(p[i]).Convert(in)
    }
    method.Call(parameterValues)
    return nil
}
Salin selepas log masuk

Untuk mengelakkan panik, kod ini menyemak sama ada penukaran dibenarkan sebelum menukar.

Jalankan kod di PlayGround!

Atas ialah kandungan terperinci Adakah terdapat cara yang baik untuk menjadikan jenis angka sesuai untuk 'kaedah.Panggilan' dalam golang?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

sumber:stackoverflow.com
Kenyataan Laman Web ini
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn
Tutorial Popular
Lagi>
Muat turun terkini
Lagi>
kesan web
Kod sumber laman web
Bahan laman web
Templat hujung hadapan
Tentang kita Penafian Sitemap
Laman web PHP Cina:Latihan PHP dalam talian kebajikan awam,Bantu pelajar PHP berkembang dengan cepat!