d可有可空指针

原文
非空针:

int* p = ...;
nonnull int* np = isPtrNull(p) ? fatalError("这是null") : p;
*np = 3;//不会失败
//可空针
int* p = ...;
*p = 3;? // 段错误!

特意选择了不重要的示例,因为你目的是专门解引用,可空针.
我关心该示例:

nonnull int* p = ...; //可能是编译时错误
*p = 3; //无运行时检查.无段错误!

注意声明解引用可能相隔几个函数调用,两者相隔越远,在类型系统中跟踪它,就越有用.
程序中,只要可单独处理空值(null),就可用手动检查,来转换可空针非空针.这只是求和类型的特例,编译器会检查是否彻底处理所有情况.
'null'提供的特别有效标签编码只是小细节.

在此的主要抱怨并不是特别针对段错误(尽管没用),而是崩溃致命性和隐含性.
不处理空(null),就转换可空针非空针本质就是不安全操作.D当前隐式这样.对会完全崩溃程序的致命运行时错误,显式优于隐式.

一般,使用非空针,不会得到致命错误,如果有非平凡逻辑来决定某个指针是否应为空,要在运行时显式检查该不变量.

经验是,空针段错误一般发生在,不希望出现空针的地方(且应用非空针,来使类型系统确保调用者提供它),或应用不同逻辑检查空(null).因为忘记考虑到空针.
语言在检查类型时,通过按非空针引用,来避免思考它.然后一旦不可避免地违反了非空针,就会在运行时隐式崩溃.

非空针允许在类型系统表达此假设,它们比运行时段错误断定失败更有用,因为它们记录了期望,及坏的空针错误源.
巧妙改变函数的接口更容易产生运行时段错误/断定失败,而通过内部检查及忽略null而不是解决根本问题,使问题更复杂.尤其是在大量未记录的代码中,很难找到根问题.而Nonnull是编译器检查文档,它会默认引导注意力实际错误函数.

不,不需要运行时检查来解引用非空针.

nonnull x = new A;

x.y = 3;//此处完全不必运行时检查

断定失败告诉我位置,因而值得额外运行时检查,有时是必要的.
顺便:我很不喜欢"nonnull指针/引用".这是默认值的奇怪反转.nonnull是更好默认值.

posted @   zjh6  阅读(15)  评论(0编辑  收藏  举报  
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示