Convert interface to float32 in go - go

Using type assertion doesn't work to convert interface{} to float32
package main
import (
"fmt"
)
func main() {
var i interface{}
i = 1.1
num, ok := i.(float32)
fmt.Println(ok)
fmt.Println(num)
}
https://play.golang.org/p/iEJWLbBCHs8
This prints false and 0. How can I convert interface{} to float32?

When the code runs:
i = 1.1
It assigns a float64 value to the variable i; that's the default type for decimal number literals in Go. When you try to convert it to float32, it fails because that's not the underlying type of i.
If you want to convert i to float32, you need to put a float32 value in it:
i = float32(1.1)
And the conversion will succeed. If you want to be able to convert to float32 or float64, you can try converting to both types, and if the conversion to float64 succeeds, you then convert the result to float32.

To answer your question:
How can I convert interface{} to float32?
Not at all.
All you can do is store a float32 in an interface{} and then type-assert it out back again. The problem with your code is that you do not store a float32.

Related

(Go Generics) IncompatibleAssign & MismatchedTypes error - Why am I receiving this error? [duplicate]

Go version: 1.18
Here's a silly example that is not particularly useful. I am using this as an exercise to learn generics.
I have a Pokemon interface
type Pokemon interface {
ReceiveDamage(float64)
InflictDamage(Pokemon)
}
and Charmander with type parameter that implements the Pokemon interface.
type Float interface {
float32 | float64
}
type Charmander[F Float] struct {
Health F
AttackPower F
}
I want to use Charmander's attack power to inflict damage.
func (c *Charmander[float64]) ReceiveDamage(damage float64) {
c.Health -= damage
}
func (c *Charmander[float64]) InflictDamage(other Pokemon) {
other.ReceiveDamage(c.AttackPower)
}
My compiler gives error
cannot use c.AttackPower (variable of type float64 constrained by Float) as float64 value in argument to other.ReceiveDamage compiler(IncompatibleAssign)
I already instantiated the struct generic as *Charmander[float64]. I'd expect that the compiler knows AttackPower is a float64.
When I pass a float64 into a function that expects float64, why should it complain? On the other hand, ReceiveDamage does not complain. I am subtracting a float64 from Health which is a constrained type.
You have to use type conversions. The method ReceiveDamage expects a float64 but the main type is parametrized in F. Something of type F, even if constrained to floats only, or even if constrained to one specific float, is not float64. It is F. (Moreover, it could also be instantiated with float32).
Both conversions compile because float64 is convertible to all types in the type parameter's type set, float32 and float64, and vice-versa.
So the methods become:
func (c *Charmander[T]) ReceiveDamage(damage float64) {
c.Health -= T(damage)
}
func (c *Charmander[T]) InflictDamage(other Pokemon) {
other.ReceiveDamage(float64(c.AttackPower))
}
Fixed playground: https://go.dev/play/p/FSsdlL8tBLn
Watch out that the conversion T(damage) may cause loss of precision when T is instantiated with float32. (Probably this won't be an issue in this specific use case...)

Golang - Type decimal.Decimal convert

Trying to convert type decimal.Decimal to string
func main() {
a := strconv.Itoa(Price) // Price of type decimal.Decimal
fmt.Printf("%q\n", a)
}
Problem: cannot use (variable of type decimal.Decimal) as int value in argument to strconv.Itoa (compile)go-staticcheck
Example code that works will be apreciated
Price is decimal.Decimal not int. strconv.Itoa accepts int.
From docs https://pkg.go.dev/github.com/shopspring/decimal#Decimal.String
use .String().

Go: convert reflect.Value of type uuid.UUID (satori) back to uuid.UUID again

I'm trying to convert a reflected UUID back to an actual UUID object again but can't find a way, when I print the reflected value it looks correct, but when trying to convert I can't find a way.
package main
import (
"fmt"
"reflect"
uuid "github.com/satori/go.uuid"
)
func main() {
value := uuid.Must(uuid.NewV4())
reflectedValue := reflect.ValueOf(value)
fmt.Println(reflectedValue)
result := reflectedValue.String()
fmt.Println(result)
}
output:
$ go run main.go
0cca93f8-1763-4816-a2a0-09e7aeeb674c
<uuid.UUID Value>
How to convert reflectedValue to uuid.UUID directly or []byte/string so I can make a uuid.UUID object from that. Since fmt.Println manages to print the correct value it has to be possible to make the conversion, but I can't figure out how.
It seem like the uuid.UUID object has a data structure of 16 uint8 values.
Use a type assertion on the underlying value:
u, ok := reflectedValue.Interface().(uuid.UUID)

interface conversion: interface {} is uint64, not float32

Basically I have map[interface{}]interface{} and inside under key "x" value 90 (I printed to confirm that data are correct), but when I do
mymap["x"].(float32)
I get error
interface conversion: interface {} is uint64, not float32
Problem is that I expect float number (produced from as output from another program). I also tried to float32(mymap["x"]) but not success(also tried examples from google with int64 without success).
I am using go version go1.10.1 linux/amd64
this is my script:
switch i := x.(type) {
case nil:
printString("x is nil") // type of i is type of x (interface{})
case int:
printInt(i) // type of i is int
case float64:
printFloat64(i) // type of i is float64
case func(int) float64:
printFunction(i) // type of i is func(int) float64
case bool, string:
printString("type is bool or string") // type of i is type of x (interface{})
default:
printString("don't know the type") // type of i is type of x (interface{})
}

Convert string to float32?

There is an input that I need to read from the console as a string, then manipulate the string and convert some of it to float32.
I have tried using:
float, _ := strconv.ParseFloat(myString, 32)
But it does not work. This is the error I get:
cannot use float (type float64) as type float32 in field value
Is there anything else I could do?
Thanks!
float has the type float32, but strconv.ParseFloat returns float64. All you need to do is convert the result:
// "var float float32" up here somewhere
value, err := strconv.ParseFloat(myString, 32)
if err != nil {
// do something sensible
}
float = float32(value)
Depending on the situation, it may be better to change float's type to float64.

Resources