Architecture 制作一致的API,什么';那就不那么令人惊讶了?

Architecture 制作一致的API,什么';那就不那么令人惊讶了?,architecture,language-agnostic,Architecture,Language Agnostic,我有一个API,其中包含属性访问器,如: int foo() 有时属性可以是“null”。由于int不能为null,因此使用额外的属性来检查null bool hasFoo() 当foo()为null时,人们调用它会发生什么?foo()的实现不会有未定义的行为,而是在内部检查hasFoo()和panic,这通常会使用错误消息终止线程或进程 使用浮动会让事情变得更有趣。此API中的浮点具有空值:NaN。所以 float bar() 当hasBar()返回false时,bar将始终返回NaN,

我有一个API,其中包含属性访问器,如:

int foo()
有时属性可以是“null”。由于int不能为null,因此使用额外的属性来检查null

bool hasFoo()
当foo()为null时,人们调用它会发生什么?foo()的实现不会有未定义的行为,而是在内部检查hasFoo()和panic,这通常会使用错误消息终止线程或进程

使用浮动会让事情变得更有趣。此API中的浮点具有空值:NaN。所以

float bar()
当hasBar()返回false时,bar将始终返回NaN,这是定义非常好的beahvior。事实上,大多数类型、字符串、日期等都有有效的“null”表示。整数和布尔是奇数,其中0可以是有效值


所以我的问题是,当hasBar()为false以与int和bools一致时,bar()是否也会恐慌?或者,当int和bool为null时,它们应该返回0,只有通过调用hasFoo()才能区分实0和null 0。什么行为不那么令人惊讶?为什么?

如果API将返回可为null的值,作为开发人员,我最希望返回类型是可为null的,如果语言支持它()

按照这些思路,如果您期望作为常规用例会有很多空值,那么最好创建一个返回的包装器响应对象,类似于下面的伪代码示例:

public class Response<T>()
{
    bool HasValue { get; }
    T Value { get; }
}
公共类响应()
{
bool HasValue{get;}
T值{get;}
}

因此,使用这种方法,您将返回Response而不是int,以及Response而不是float…等等

如果API将返回可为null的值,作为开发人员,我最希望返回类型是可为null的,如果语言支持它()

按照这些思路,如果您期望作为常规用例会有很多空值,那么最好创建一个返回的包装器响应对象,类似于下面的伪代码示例:

public class Response<T>()
{
    bool HasValue { get; }
    T Value { get; }
}
公共类响应()
{
bool HasValue{get;}
T值{get;}
}

因此,使用这种方法,您将返回Response而不是int,以及Response而不是float…等等

如果API将返回可为null的值,作为开发人员,我最希望返回类型是可为null的,如果语言支持它()

按照这些思路,如果您期望作为常规用例会有很多空值,那么最好创建一个返回的包装器响应对象,类似于下面的伪代码示例:

public class Response<T>()
{
    bool HasValue { get; }
    T Value { get; }
}
公共类响应()
{
bool HasValue{get;}
T值{get;}
}

因此,使用这种方法,您将返回Response而不是int,以及Response而不是float…等等

如果API将返回可为null的值,作为开发人员,我最希望返回类型是可为null的,如果语言支持它()

按照这些思路,如果您期望作为常规用例会有很多空值,那么最好创建一个返回的包装器响应对象,类似于下面的伪代码示例:

public class Response<T>()
{
    bool HasValue { get; }
    T Value { get; }
}
公共类响应()
{
bool HasValue{get;}
T值{get;}
}
因此,使用这种方法,您将返回Response而不是int,以及Response而不是float…等等

案例1:hasBar()为false时,bar()也会死机

这对我来说并不奇怪,因为如果我没有给一个浮点赋值,我不应该期望从它得到任何回报。返回NaN是一种方便的方法,可以避免程序中出现异常并让它完成它试图做的事情,但如果您正在设计自己的实现方法,这就不那么令人惊讶了。但这会带来其他问题,因为您必须捕获抛出的每个异常,并以某种优雅的方式进行处理

案例2:只有调用hasFoo()才能区分实0和空0的区别

这肯定会让人惊讶,因为不是每个人都知道他们需要检查另一个值来验证这是否为实际的0,但您将在这里优雅地处理异常。

案例1:bar()在hasBar()为false时也会死机。

这对我来说并不奇怪,因为如果我没有给一个浮点赋值,我不应该期望从它得到任何回报。返回NaN是一种方便的方法,可以避免程序中出现异常并让它完成它试图做的事情,但如果您正在设计自己的实现方法,这就不那么令人惊讶了。但这会带来其他问题,因为您必须捕获抛出的每个异常,并以某种优雅的方式进行处理

案例2:只有调用hasFoo()才能区分实0和空0的区别

这肯定会让人惊讶,因为不是每个人都知道他们需要检查另一个值来验证这是否为实际的0,但您将在这里优雅地处理异常。

案例1:bar()在hasBar()为false时也会死机。

这对我来说并不奇怪,因为如果我没有给一个浮点赋值,我不应该期望从它得到任何回报。返回NaN是一种方便的方法,可以避免程序中出现异常并让它完成它试图做的事情,但如果您正在设计自己的实现方法,这就不那么令人惊讶了。但这会带来其他问题,因为您必须捕获抛出的每个异常,并以某种优雅的方式进行处理

案例2:只有调用hasFoo()才能区分实0和空0的区别

这肯定会令人惊讶,因为不是每个人都知道他们需要检查另一个值来验证这是否为实际的0,但您将处理