作为评估项目的一部分,我正在将现有的C ++应用程序移植到GO。在此过程中,我需要读取两个数据集属性,在某些文件中该属性存储为double值,在某些文件中为float值。我用来处理此问题的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”包。)read方法似乎很简单:
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与double或float的ID不同。
我已经浏览过https://godoc.org/gonum.org/v1/hdf5
上的在线文档,但是无法找到解决我问题的方法。 (或使用GO读取HDF5属性的任何示例。)
有人能做这样的事情吗?还是大多数示例只是假设类型而不是查询类型?
答案 0 :(得分:0)
我已经证实了自己的怀疑,现在有一个正确的答案。根本的问题是,我在使用C ++ API时出现错误(在某些情况下,这只会导致写入两倍的double值),而我实际上是在尝试在GO中重复该错误。实际上,解决方案非常简单。
传递到属性myAdapter.setHasStableIds(true);
方法中的属性类型不是属性的类型,而是存储在内存中时要转换为的类型。这意味着我的C ++代码应该简单得多,因为不需要检查属性类型,也不需要将其read
生成结果。要读取和存储属性值,只需依赖HDF5进行转换,并在属性不可转换为双精度的情况下抛出适当的异常就很简单
static_cast
GO版本的工作量更大,因为我们必须手动管理对象生命周期和错误条件,但实际情况是这样。 (请注意,我假设“ ...处理错误...”还涉及提前退出,否则需要额外的if语句来检查att是否为nil。)
const auto att = dataSet.openAttribute("my attribute name");
att.read(H5::PredType::NATIVE_DOUBLE, &attributeValue);