问题描述
我来自 Javascript,我不明白以下概念。通过执行下面我想要的代码,我得到了“(苹果,橙色)”。但是我想知道为什么我不必调用迭代器函数来获取迭代器?比如“print(MyString(["apple","orange"]).iterator);”
void main() {
print(MyString(["apple","orange"]));
}
class MyString extends Iterable<String>{
MyString(this.strings);
final List<String> strings;
Iterator<String> get iterator => strings.iterator;
}
解决方法
原因是您从 Iterable
扩展,这是一个抽象类。这个类包含很多方法,但不包含任何 get iterator
的实现。因此,当您从 Iterable
扩展时,您需要提供此字段的实现。
您从 Iterable
获得的方法之一是 toString()
实现,如下所示:
String toString() => IterableBase.iterableToShortString(this,'(',')');
因此现在将使用此 toString()
,而不是默认情况下您将获得的 Object
。
这很重要的原因是因为当你这样做时:
print(MyString(["apple","orange"]));
print
已实现,因此如果给定对象不是 String
,它将调用该对象上的 toString()
方法。因此,在您的情况下,我们正在对您的 toString()
对象调用 MyString
方法。由于 MyString
没有实现 toString()
,它会尝试在 toString()
的类层次结构中查找 MyString
。在您的情况下,最近的 toString()
实现方法是来自 Iterable
的方法。
toString()
上的 Iterable
方法记录为:
返回 this
的(部分)元素的字符串表示。
元素由它们自己的 toString
结果表示。
默认表示总是包含前三个元素。如果迭代中的元素少于一百个,则它还包含最后两个元素。
如果结果字符串不超过 80 个字符,则从可迭代对象的开头开始包含更多元素。
如果已知某些元素不会出现在输出中,则转换可能会省略对这些元素的调用 toString
,并且可能会在一百个元素后停止迭代。
https://api.dart.dev/stable/2.12.4/dart-core/Iterable/toString.html
此方法也使用 get iterator
字段来输出元素。所以这就是为什么当你这样做时它似乎“正常工作”:
print(MyString(["apple","orange"]));
但您应该注意,print
实际上并没有直接使用 get iterator
字段,而只是使用从 String
返回的 toString()
。此外,toString()
中的 Iterable
不会输出 Iterable
中的所有元素,正如您在文档中所读到的那样。