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
是更好默认值.
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现