如何使用 GO 语言读取可能是两种不同数据类型之一的 HDF5 属性?

作为评估项目的一部分,我正在将现有的 C++ 应用程序移植到 GO。作为其中的一部分,我需要读取两个数据集属性,这些属性在一些文件中存储为双精度,在一些文件中存储为浮点数。我用来处理这个问题的 C++ 代码如下所示(我们在 Debian Linux 上使用 libhdf5-cpp-100)。


const auto att = dataSet.openAttribute(attributeName);

if (att.getDataType() == H5::PredType::NATIVE_DOUBLE) {

    att.read(att.getDataType(), &attributeValue);

}

else if (att.getDataType() == H5::PredType::NATIVE_FLOAT) {

    float temp = 0.F;

    att.read(att.getDataType(), &temp);

    attributeValue = static_cast<double>(temp);

}

else {

    // we throw an exception indicating we don't support the type

}

我的问题是我无法在 GO 中编写等效项。(我正在使用包“gonum.org/v1/hdf5”。)读取方法似乎很简单:


func (s *Attribute) Read(data interface{}, dtype *Datatype) error

但是我正在努力确定要传递什么作为数据类型,因为属性类型似乎没有 GetDataType 方法。我看到的最接近的是:


func (s *Attribute) GetType() Identifier

但这不返回数据类型,它返回一个标识符。我在假设给定标识符我可以确定数据类型的情况下尝试了以下比较:


if attr.GetType().ID() == hdf5.T_NATIVE_DOUBLE.ID() {

    // handle as a double

}

但这是行不通的。从 GetType() 返回的 ID 与双精度型或浮点型的 ID 不同。


我已经浏览过在线文档,https://godoc.org/gonum.org/v1/hdf5但无法找到解决我的问题的方法。(或使用 GO 读取 HDF5 属性的任何示例。)


有没有人设法做这样的事情?还是大多数示例只是假定类型而不是查询类型?


至尊宝的传说
浏览 136回答 1
1回答

慕的地8271018

我已经证实了我的怀疑,现在有了正确的答案。根本问题是我在使用 C++ API 时出错(在某些情况下这会导致只写 1/2 的双精度数),而我实际上是在尝试在 GO 中重复这个错误。其实解决方法很简单。传递到属性方法中的属性类型read不是属性的类型,而是存储在内存中时您希望将其转换为的类型。这意味着我的 C++ 代码应该简单得多,因为不需要检查属性类型,也不需要检查static_cast结果。要读取和存储属性值,依靠 HDF5 执行转换并在属性不可转换为双精度值时抛出合适的异常,非常简单const auto att = dataSet.openAttribute("my attribute name");att.read(H5::PredType::NATIVE_DOUBLE, &attributeValue);GO 版本的工作量更大,因为我们必须手动管理对象生命周期和错误条件,但就在这里。(请注意,我假设“...处理错误...”也涉及提前退出,否则需要额外的 if 语句来检查 att 是否为 nil。)att, err := dataSet.OpenAttribute("my attribute name")if err != nil {&nbsp; &nbsp; ...handle the error...}err = att.Read(&attributeValue, hdf5.T_NATIVE_DOUBLE)if err != nil {&nbsp; &nbsp; ...handle the error...}err = att.Close()if err != nil {&nbsp; &nbsp; ...handle the error...}
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go