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

时间:2022-09-16 11:18:27

I've seen two alternative conventions used when specifying a range of indexes, e.g.

我已经看到了在指定一系列索引时使用的两种替代约定,例如

subString(int startIndex, int length);

vs.

subString(int startIndex, int endIndex);

They are obviously equivalent in terms of what you can do with them, the only difference being whether you specify the ending index or the length of the range.

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

I'm assuming that in all cases startIndex would be inclusive, and endIndex exclusive.

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

Are there any compelling reasons to prefer one over the other when defining an API?

在定义API时,是否有任何令人信服的理由更喜欢一个而不是另一个?

4 个解决方案

#1


6  

I'd prefer the length one simply because it gives me one less question to ask/look up in the documentation.

我更喜欢长度一个,因为它让我在文档中询问/查询一个问题。

For the endIndex based one - is that an inclusive or exclusive end point?

对于基于endIndex的一个 - 是一个包容性或独占的终点?

(For either variant, the same question could be asked about startIndex, but it would be a perverse API that makes it exclusive).

(对于任何一个变体,可以询问有关startIndex的相同问题,但它将是一个反常的API,使其独占)。

#2


3  

How to disambiguate positional arguments...

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

  1. use longer names subStringFromUpto( startIndex , stopIndex )

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

  2. use uniform convention across the whole library

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

Didn't we find better after all these years ?

这些年来,我们没有发现好转吗?

Ah yes, in Smalltalk maybe, since the question is tagged language-agnostic...

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

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

Less ambiguity, but maybe we'll have to wait another 30 years before larger adoption of such style
(it probably looks too much simple to be serious)

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

#3


2  

This is a good question and I think the preference for which to use comes down to what are the most common use cases. Most use cases are equally simple using either API, but consider this one:

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

You want to get a substring that starts at 5 and ends at the end of the string. Using the index based version (assuming it's second index is exclusive), it's as simple as:

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

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

With the length based API:

使用基于长度的API:

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

That second approach is much less succinct and obvious. However, this can be solved by simply stating that if the length will cause an overflow of the remaining string, it will gracefully support that (e.g. str.subString(5, str.length()); would grab everything from index 5 to the end even though it may be asking for more characters than are left). Ruby does this with their String#splice method in addition to supporting advanced things like negative indices.

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

In my opinion, the index based approach is more concrete, especially when negative indices aren't allowed. This makes it very obvious what to expect from the API, which can be a good thing; making it harder to shoot yourself in the foot. However, a well documented API, like Ruby, makes it easy to empower the programmer and can make for some graceful substring-ing.

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

I also find that in general, when I'm performing substring operations, that I often know my beginning and end points. With the length based approach, that's going to require an additional calculation when calling the API (e.g. substring(startIndex, endIndex - startIndex)).

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

#4


0  

Someone should do a study of typical call sites to find out which approach yields more succinct code (and therefore probably correct code).

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

I like the argument that using 'length' you don't have to look at the documentation, but you may already be looking at the documentation to determine whether the 2nd integer is the 'end' or the 'length'. If you name it endExclusive, then it's just as self-documenting.

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

#1


6  

I'd prefer the length one simply because it gives me one less question to ask/look up in the documentation.

我更喜欢长度一个,因为它让我在文档中询问/查询一个问题。

For the endIndex based one - is that an inclusive or exclusive end point?

对于基于endIndex的一个 - 是一个包容性或独占的终点?

(For either variant, the same question could be asked about startIndex, but it would be a perverse API that makes it exclusive).

(对于任何一个变体,可以询问有关startIndex的相同问题,但它将是一个反常的API,使其独占)。

#2


3  

How to disambiguate positional arguments...

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

  1. use longer names subStringFromUpto( startIndex , stopIndex )

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

  2. use uniform convention across the whole library

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

Didn't we find better after all these years ?

这些年来,我们没有发现好转吗?

Ah yes, in Smalltalk maybe, since the question is tagged language-agnostic...

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

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

Less ambiguity, but maybe we'll have to wait another 30 years before larger adoption of such style
(it probably looks too much simple to be serious)

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

#3


2  

This is a good question and I think the preference for which to use comes down to what are the most common use cases. Most use cases are equally simple using either API, but consider this one:

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

You want to get a substring that starts at 5 and ends at the end of the string. Using the index based version (assuming it's second index is exclusive), it's as simple as:

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

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

With the length based API:

使用基于长度的API:

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

That second approach is much less succinct and obvious. However, this can be solved by simply stating that if the length will cause an overflow of the remaining string, it will gracefully support that (e.g. str.subString(5, str.length()); would grab everything from index 5 to the end even though it may be asking for more characters than are left). Ruby does this with their String#splice method in addition to supporting advanced things like negative indices.

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

In my opinion, the index based approach is more concrete, especially when negative indices aren't allowed. This makes it very obvious what to expect from the API, which can be a good thing; making it harder to shoot yourself in the foot. However, a well documented API, like Ruby, makes it easy to empower the programmer and can make for some graceful substring-ing.

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

I also find that in general, when I'm performing substring operations, that I often know my beginning and end points. With the length based approach, that's going to require an additional calculation when calling the API (e.g. substring(startIndex, endIndex - startIndex)).

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

#4


0  

Someone should do a study of typical call sites to find out which approach yields more succinct code (and therefore probably correct code).

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

I like the argument that using 'length' you don't have to look at the documentation, but you may already be looking at the documentation to determine whether the 2nd integer is the 'end' or the 'length'. If you name it endExclusive, then it's just as self-documenting.

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