doudeng5764
doudeng5764
2015-09-17 17:57
浏览 65

从gomobile绑定评估nil值

What's the right way to evaluate nil returned values from Go functions in Android Java?

Here's what I've tried:

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

Then I generate a .aar file via gomobile using:

gomobile bind -v --target=android

In my Java code I tried to evaluate nil as null but it's not working. Java Code:

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

Disclaimer: Other methods from the go library work flawless

图片转代码服务由CSDN问答提供 功能建议

什么是评估 nil Go Android Java中的功能?

这是我尝试过的方法:

  //如果失败,ExportedGoFunction返回指向GoStruct或nil的指针
func ExportedGoFunction  ()* GoStruct {
 return nil 
} 
   
 
 

然后我使用以下方法通过gomobile生成.aar文件:

gomobile bind -v --target = android

在我的Java代码中,我尝试将 nil 评估为 null < / strong>,但无法正常工作。 Java代码:

  GoLibrary.GoStruct goStruct = GoLibrary.ExportedGoFunction(); 
if(goStruct!= null){
 //不应执行此块,但是 is 
 Log.d(“ GoLog”,“ goStruct不为null”); 
} 
   
 
 

免责声明:go库中的其他方法可以正常工作< / p>

  • 点赞
  • 写回答
  • 关注问题
  • 收藏
  • 邀请回答

2条回答 默认 最新

  • douwen1901
    douwen1901 2015-09-21 01:14
    已采纳

    For possible future reference, as of 09/2015 I've come up with two ways of dealing with the problem.

    The first one is to return an error from the Go code and try/catch-ing the error in Java. Here's an example:

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

    And then try/catch the error in Java

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

    This approach is both idiomatic Go and Java, but even if it works on preventing the program to crash, it ends up bloating the code with try/catch statements and causing yet more overhead.

    So, based on user @SnoProblem answers the non-idiomatic way of solving it and properly handle null values I came up with was:

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

    And then check the code in Java like:

    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");
    }
    
    点赞 评论
  • douwei2713
    douwei2713 2015-09-18 00:52

    Looking through the testing package for go mobile, it looks like you need to cast the null value to the type.

    From the SeqTest.java file:

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

    Edit: A non-exception example, too:

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

    It may be as simple as:

    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");
    }
    

    EDIT: Suggestion for utility method:

    You could add a utility function to the library to give you the typed nil value.

    func NullVal() *GoStruct {
        return nil
    }
    

    Still a bit hacky, but it should be less overhead than multiple wrappers and exception handling.

    点赞 评论

相关推荐