API设计中的(开始,结束)与(开始,长度)

时间:2013-01-11 05:29:49

标签: api language-agnostic coding-style api-design

在指定索引范围时,我看到了两种替代约定,例如

subString(int startIndex, int length);

VS

subString(int startIndex, int endIndex);

它们在你可以用它们做什么方面显然是等价的,唯一的区别在于你是指定结束索引还是指定范围的长度。

我假设在所有情况下startIndex都是包容性的,而endIndex是独占的。

在定义API时,是否有任何令人信服的理由偏好另一个?

4 个答案:

答案 0 :(得分:6)

我更喜欢length一个,因为它让我在文档中提问/查询的问题少了一些。

对于基于endIndex的那个 - 是包容性的还是排他性的终点?

(对于任何一种变体,同样的问题可能会被问及startIndex,但这将是一个反常的API,使其成为独家的。

答案 1 :(得分:3)

如何消除位置论证的歧义......

  1. 使用更长的名称subStringFromUpto(startIndex,stopIndex)

  2. 在整个图书馆中使用统一的约定

  3. 这些年来,我们难道不是更好吗?

    啊,是的,在Smalltalk中可能,因为这个问题被标记为与语言无关......

    aString copyFrom: startIndex to: stopIndex.
    aString substringOfLength: length startingAt: startIndex.
    

    不那么模棱两可,但也许我们不得不再等30年才能更广泛地采用这种风格 (它可能看起来太简单了)

答案 2 :(得分:2)

这是一个很好的问题,我认为使用它的偏好取决于最常见的用例。大多数用例使用任一API都同样简单,但请考虑这个:

您希望获得一个从5开始并在字符串结尾处结束的子字符串。使用基于索引的版本(假设它的第二个索引是独占的),它就像:

一样简单
str.subString(5, str.length());

使用基于长度的API:

str.subString(5, str.length() - 5);

第二种方法不那么简洁明了。但是,这可以通过简单地说明如果长度将导致剩余字符串溢出来解决,它将优雅地支持(例如str.subString(5, str.length());将从索引5到结尾抓取所有内容,即使它可能要求比剩下更多的字符)。除了支持负面索引等高级内容之外,Ruby还使用String#splice方法执行此操作。

在我看来,基于指数的方法更具体,特别是在不允许负指数的情况下。这使得对API的期望非常明显,这可能是一件好事;让你更难在脚下射击自己。但是,一个记录良好的API,比如Ruby,可以很容易地为程序员赋权,并且可以为一些优雅的子字符串提供支持。

我也发现,一般来说,当我执行子串操作时,我经常知道我的起点和终点。使用基于长度的方法,在调用API时需要额外的计算(例如substring(startIndex, endIndex - startIndex))。

答案 3 :(得分:0)

有人应该对典型的呼叫站点进行研究,以找出哪种方法产生更简洁的代码(因此可能是正确的代码)。

我喜欢使用“长度”你不必查看文档的论点,但你可能已经在查看文档以确定第二个整数是'结束'还是'长度'。如果你将它命名为endExclusive,那么它就像自我记录一样。