2

在Android Java中评估Go函数的nil返回值的正确方法是什么?

这是我尝试过的:

// ExportedGoFunction returns a pointer to a GoStruct or nil in case of fail
func ExportedGoFunction() *GoStruct {
  return nil
}

然后我使用以下命令通过 gomobile 生成一个 .aar 文件:

gomobile bind -v --target=android

在我的 Java 代码中,我尝试将nil评估为null但它不起作用。Java 代码:

GoLibrary.GoStruct goStruct = GoLibrary.ExportedGoFunction();
if (goStruct != null) {
   // This block should not be executed, but it is
   Log.d("GoLog", "goStruct is not null");
}

免责声明:go 库中的其他方法完美无缺

4

2 回答 2

1

查看 go mobile 的测试包,您似乎需要将 null 值转换为类型。

从 SeqTest.java 文件:

 public void testNilErr() throws Exception {
    Testpkg.Err(null); // returns nil, no exception
  }

编辑:也是一个非异常示例:

byte[] got = Testpkg.BytesAppend(null, null);
assertEquals("Bytes(null+null) should match", (byte[])null, got);
got = Testpkg.BytesAppend(new byte[0], new byte[0]);
assertEquals("Bytes(empty+empty) should match", (byte[])null, got);

它可能很简单:

GoLibrary.GoStruct goStruct = GoLibrary.ExportedGoFunction();
if (goStruct != (GoLibrary.GoStruct)null) {
   // This block should not be executed, but it is
   Log.d("GoLog", "goStruct is not null");
}

编辑:实用方法的建议:

您可以向库中添加一个实用函数来为您提供键入的nil值。

func NullVal() *GoStruct {
    return nil
}

仍然有点 hacky,但它应该比多个包装器和异常处理更少的开销。

于 2015-09-18T00:52:31.070 回答
1

为了将来可能的参考,截至09/2015,我提出了两种解决问题的方法。

第一个是从Go代码中返回错误并尝试/​​捕获Java中的错误。这是一个例子:

// ExportedGoFunction returns a pointer to a GoStruct or nil in case of fail
func ExportedGoFunction() (*GoStruct, error) {
   result := myUnexportedGoStruct()
   if result == nil {
      return nil, errors.New("Error: GoStruct is Nil")
   }

   return result, nil
}

然后尝试/捕获Java中的错误

try {
   GoLibrary.GoStruct myStruct = GoLibrary.ExportedGoFunction();
} 
catch (Exception e) {
   e.printStackTrace(); // myStruct is nil   
}

这种方法既是GoJava的惯用方法,但即使它可以防止程序崩溃,它最终也会使用 try/catch 语句使代码膨胀并导致更多开销。

因此,基于用户@SnoProblem回答了非惯用的解决方法并正确处理我想出的空值是:

// NullGoStruct returns false if value is nil or true otherwise
func NullGoStruct(value *GoStruct) bool {
    return (value == nil) 
}

然后检查Java中的代码,如:

GoLibrary.GoStruct value = GoLibrary.ExportedGoFunction();
if (GoLibrary.NullGoStruct(value)) {
   // This block is executed only if value has nil value in Go
   Log.d("GoLog", "value is null");
}
于 2015-09-21T01:14:06.937 回答