首页 > 解决方案 > 我们可以在不“手动”构造的情况下在数组和结构之间进行转换吗?

问题描述

我有一个结构来表示 3D 空间中的向量。

type Vec3 struct {
    X, Y, Z float64
}

我正在使用的另一个库做了类似但不同的事情:

type Vector [3]float64

据我了解,这两种类型都应占用 24 个字节,并且float64一种类型中的每种都应与float64另一种类型中的 a 对齐。因此,我们应该能够毫不费力地从一个分配到另一个。然而,编译器不喜欢尝试隐式或显式地强制转换,因此最干净(但冗长)的方法似乎总是手动构造值:

// Vec3 to Vector
vec3 := Vec3{1, 2, 3}
vector := Vector{vec3.X, vec3.Y, vec3.Z}

// Vector to Vec3
vector := Vector{1, 2, 3}
vec3 := Vec3{vector[0], vector[1], vector[2]}

我发现的另一种方法如下,但它看起来同样冗长(而且可能更慢(如果其中一种类型发生变化,它不会阻止我们))。

valueOfTargetType := *(*targetType)(unsafe.Pointer(&sourceValue))

那么,我们可以在不显式构造新值的情况下转换它们吗?

标签: go

解决方案


对于将被内联的简洁解决方案,请使用方法。

例如,

package main

import "fmt"

type Vec3 struct {
    X, Y, Z float64
}

func (v Vec3) Vector() Vector {
    return Vector{v.X, v.Y, v.Z}
}

type Vector [3]float64

func (v Vector) Vec3() Vec3 {
    return Vec3{X: v[0], Y: v[1], Z: v[2]}
}

func main() {
    v3 := Vec3{X: 1, Y: 2, Z: 3}
    v3v := v3.Vector()
    fmt.Println(v3, v3v)

    v := Vector{4, 5, 6}
    vv3 := v.Vec3()
    fmt.Println(v, vv3)
}

输出:

{1 2 3} [1 2 3]
[4 5 6] {4 5 6}

推荐阅读