Можем ли мы конвертировать массивы и структуры, не создавая «вручную»? - PullRequest
0 голосов
/ 24 октября 2018

У меня есть структура для представления вектора в трехмерном пространстве.

type Vec3 struct {
    X, Y, Z float64
}

Другая библиотека, которую я использую, делает что-то похожее, но другое:

type Vector [3]float64

Насколько я понимаю, обатипы должны занимать 24 байта, и каждый float64 в одном типе должен совпадать с float64 в другом типе.Таким образом, мы должны иметь возможность назначать один другому без особых проблем.Однако компилятору не нравится пытаться привести их ни к простоте, ни к явному, поэтому самый чистый (но многословный) метод заключается в том, чтобы всегда конструировать значение вручную:

// 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))

Итак, можем ли мы привести их без явного создания нового значения?

Ответы [ 2 ]

0 голосов
/ 24 октября 2018

Для краткого решения, которое будет встроено, используйте методы.

Например,

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}
0 голосов
/ 24 октября 2018

конвертировать между массивами и структурами без копирования?

Нет.

Что я собираюсь сделать, это сделать поставку Vec3d вместо [3] float64 вводитьбез снижения производительности

Учитывая, что невозможно преобразовать массивы в структуры без копирования, я бы посоветовал предварительно загрузить ваше копирование type Vec3 -> [3]float64 в начале программыпоэтому вы не будете испытывать никаких штрафов во время основного цикла.

присваивайте одно другому без копирования (или других медленных накладных расходов)

Сначала подумайте о завершении программычтобы увидеть, приемлема ли производительность для конечных пользователей.

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

Надеюсь, это поможет.Cheers,

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...