当程序员抱怨空错误/异常时,有人经常会问我们做什么而没有null.
我对选项类型的酷感有一些基本的想法,但我没有最好的表达它的知识或语言技巧.对于普通程序员可以接近的方式写的以下内容有什么好的解释,我们可以指出那个人?
null programming-languages functional-programming nullpointerexception non-nullable
如果我有一个可空类型Xyz?,我想引用它或将其转换为非可空类型Xyz.在Kotlin这样做的惯用方法是什么?
例如,此代码出错:
val something: Xyz? = createPossiblyNullXyz()
something.foo() // Error: "Only safe (?.) or non-null asserted (!!.) calls are allowed on a nullable receiver of type Xyz?"
Run Code Online (Sandbox Code Playgroud)
但是,如果我首先检查null是允许的,为什么?
val something: Xyz? = createPossiblyNullXyz()
if (something != null) {
something.foo()
}
Run Code Online (Sandbox Code Playgroud)
假设我确定它确实从未如此,如何null在不需要if检查的情况下更改或处理值null?例如,在这里,我从地图中检索一个我可以保证存在的值而结果get()不是null.但是我有一个错误:
val map = mapOf("a" to 65,"b" to 66,"c" to 67)
val something = map.get("a")
something.toLong() // Error: "Only safe (?.) or non-null asserted (!!.) calls …Run Code Online (Sandbox Code Playgroud) 我有一个具有以下签名的功能
public static String myFunction(@Nonnull String param)
Run Code Online (Sandbox Code Playgroud)
当我用param调用它为null时,我得到以下异常:
Caused by: java.lang.IllegalArgumentException: Argument for @Nonnull parameter 'param' of com/MyClass.myFunction must not be null
at com.MyClass.$$$reportNull$$$0(MyClass.java)
Run Code Online (Sandbox Code Playgroud)
不应该在运行时检查javax.annotation.Nonnull.
谁真的抛出异常,为什么?
PS我使用Oracle JDK 1.8.0_102从IntelliJ IDEA 2016.3以调试模式运行Tomcat服务器
为什么不允许在C#中为null分配null?这是如何实现的?是否可以使用此功能使您自己的类不可为空?
例:
string stringTest = null; // Okay
DateTime dateTimeTest = null; // Compile error
Run Code Online (Sandbox Code Playgroud)
我知道我可以DateTime?在C#2.0中使用以允许将null分配给dateTimeTest,并且我可以在我的字符串上使用Jon Skeet的NonNullable类来获取stringTest赋值的运行时错误.我只是想知道为什么这两种类型的行为不同.
我有一个 DTO,它是通过从 DynamoDB 表中读取来填充的。说它目前看起来像这样:
public class Item
{
public string Id { get; set; } // PK so technically cannot be null
public string Name { get; set; } // validation to prevent nulls but this doesn't stop database hacks
public string Description { get; set; } // can be null
}
Run Code Online (Sandbox Code Playgroud)
是否有任何最佳实践来处理这个问题?我宁愿避免使用非无参数构造函数,因为它与 Dynamo SDK(以及其他)中的 ORM 的关系很差。
写起来对我来说似乎很奇怪,public string Id { get; set; } = "";因为这永远不会发生,因为它Id是一个 PK 并且永远不会为空。""即使它以某种方式做了,又有什么用呢?
那么这方面有什么最佳实践吗?
string?说它们可以为空,即使有些永远不应该。 …当从Kotlin调用非可空性注释的Java函数时,我们得到灵活类型的返回值,用感叹号表示,例如String!.
Kotlin默默地允许将这些灵活值分配给正常的非null类型,例如String,这可能在运行时导致NullPointerExceptions.
我更希望得到编译器警告或错误的此类分配.或者,将平台类型视为等效于可空类型(例如String?).
例如,使用此Java代码:
import android.os.SystemClock;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
public class NullTest {
private String maybe() {
if (SystemClock.elapsedRealtimeNanos() % 2 == 0) {
return null;
}
return "ok";
}
public String annotatedNothing() { return maybe(); }
@Nullable public String annotatedNullable() { return maybe(); }
@NonNull public String annotatedNonNull() { return "ok"; }
}
Run Code Online (Sandbox Code Playgroud)
...以及以下Kotlin代码,我想在两个新行上看到错误(请参阅注释):
fun testnulls() {
val obj = NullTest()
val nullExact: String = obj.annotatedNullable() // already gives an error
val …Run Code Online (Sandbox Code Playgroud) 我想@NonNull在Android中使用注释,但我无法找到正确的方法来实现它.我建议你这个例子:
public void doStuff(@NonNull String s){
//do work with s...
}
Run Code Online (Sandbox Code Playgroud)
所以当我打电话doStuff(null)给IDE时会给我一个警告.问题是我不能依赖这个注释,因为像这个问题所指出的那样,它们不会传播得很远.所以我想对我的方法进行空检查,如下所示:
if(s==null) throw new IllegalAgrumentException();
Run Code Online (Sandbox Code Playgroud)
但是假设这个IDE s!=null会警告我s==null总是假的.我想知道最好的方法是什么.
我个人认为应该有一个注释@ShouldntBeNull,只有检查并警告null不会传递给它,但是当值为null时不会抱怨.
我读过很多不可空的问题和答案.看起来在C#(4.0)中接近不可空类型的最佳方法是Jon Skeet的NonNullable <> hack.
但是,似乎C++/CLI通过支持托管引用解决了大部分问题:( Foo%而不是本机C++ Foo&).编译器通过添加modreq(IsImplicitlyDereferenced)参数来完成此工作.试图从C#调用这样的函数会导致:
'<FunctionName>' is not supported by the language
Run Code Online (Sandbox Code Playgroud)
有没有比NonNullable <>更好的东西?
有没有办法(合理地 - 即,没有使用反射)Foo::Method(Bar%)从C#调用C++/CLI方法?
[编辑]似乎目前没有比NonNullable <>更好的了......我希望我能对C++/CLI的内容有所了解,因为它至少已经有了部分解决方案.
我有一个简单的结构,使用有限.结构是在调用数据库中的数据的方法中创建的.如果没有从数据库返回的数据我希望能够返回null,但是Visual Studio抱怨,无法将null转换为PackageName.StructName,因为它是一个不可为空的值类型.
我该如何让它可以为空?