范围和切片

我想我们都已经看到Dijkstra的著名论点 ,即应该使用包含性下限和排除性上限来表示自然数范围,并且作为推论,数组应从0开始索引。推理,尽管它未能考虑到几个反对意见,包括:

  • 对于包含负整数的范围,包含性下限/排除性上限组合(称为Dijkstra range )是不自然的。 范围start<=i<=0将被写为start<=i<1 。 Dijkstra范围令人讨厌!
  • 从零开始的索引在访问数组的最后一个元素或从数组末尾进行索引时非常不便。 谁喜欢array[length-i-1] ? 至少可以说,这种不便超过了能够写入0<=i<length而不是1<=i<length+1的便利,因此, 即使我们接受了他的论点 ,Dijkstra的情况也从零开始,从而大大破坏了这种情况。 迪克斯特拉山脉!
  • 不是两个端点是指定整数范围的唯一方法!

Ceylon没有传统的for循环,并且我们不会通过遍历列表的索引来迭代列表元素。 尽管如此,我们仍然需要一种表达整数范围的方法。 我们对这个问题的解决方案与其他语言略有不同,并且部分地拒绝了Dijkstra的结论,因此值得解释其背后的原因。

范围

我们的设计基于这样的观察: 在实践中 ,我们几乎永远不会自然地发现自己具有包含性下限/排除性上界组合。 在我们的程序中自然产生的几乎总是以下两者之一:

  • 两个(包括)端点,或
  • (包括)起点和长度。

使用Dijkstra范围,我们可以表达两种情况而不会带来太多不适:

  • start<=i<end+1
  • start<=i<start+length

因此,我们可以将Dijkstra范围的传统用法视为这两种情况之间的一种折衷:一种选择,它不会使任何选择都太痛苦。

但是,当然,通过清楚地区分这两种常见情况,很明显,这两种情况都可以进一步优化。 因此,Ceylon提供了两种表示整数范围的选项:

  • 范围运算符使用两个端点将范围表示为start..end 。 在end<start的情况下,范围为递减值。 在end==start的情况下,范围恰好具有一个值。
  • 分段范围运算符将范围的起点和长度表示为start:length 。 在长度为非正数的情况下,范围为空。

因此,这种形式的传统C风格的for循环:

for (i=0; i<length; i++) { ... }

是这样写的:

for (i in 0:length) { ... }

现在,由于整数不是我们可以形成的唯一范围,因此..:运算符可以推广为满足接口Ordinal & Comparable<T>任何类型T 因此,例如,我们可以像这样迭代英语字母的字母:

for (c in 'a'..'z') { ... }

切片

一个密切相关的问题是“切片”列表。 Python使用Dijkstra范围表示列表的一部分,因此list[start:end]包含元素list[start], list[start+1], ..., list[end-1] 。 由于上面已经给出的原因,这是一个合理的折衷。

锡兰更好,为您提供以下选择:

  • span运算符,为元素list[start], list[start+1], ..., list[end]编写了list[start..end] list[start], list[start+1], ..., list[end]
  • 运算符,为元素list[start], list[start+1], ..., list[start+length-1]编写了list[start:length] list[start], list[start+1], ..., list[start+length-1]

span和segment运算符是根据相当抽象的接口Ranged ,因此不仅仅适用于List 。 例如,平台模块ceylon.collection允许您使用这些运算符来表示SortedMapSortedSet子范围。

翻译自: https://www.javacodegeeks.com/2014/05/ranges-and-slices.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值