我在思考如何将一个序列传递给Ceylon中的序列化参数(在Java术语中为varargs参数)。考虑
void print(Object... objects) { ... }
String[] words = {"hello", "world"}; print(words); //what does this do?
第二行是否意味着我们传递了一个单独的Sequence
//Java:
print(new String[]{"hello", "world"}); //passes two Strings with a compiler warning asking for an explicit cast to Object[]
print(new Object[]{"hello", "world"}); //passes two Objects with no compiler warning
print(new String[]{"hello", "world"}, new String[]{"hello", "world"}); //passes two String[] arrays as varargs!
呃!
当存在这样的泛型方法时,事情变得更加复杂
T? first<T>(T... objects) { ... }
String[] words = {"hello", "world"}; first(words); //what type should be inferred for T?
这真会破坏我美丽的干净类型参数推断算法!这也是为什么现在出现这个问题 - 这是一个只有在实现类型分析器中的泛型类型参数推断时才会注意到的问题。
因此,我认为我们需要明确指定当你向序列化参数传递一系列值时你到底想表达什么。我对此有几种想法。
解决方案1
第一个解决方案,某种程度上受到了groovy的启发,将在位置参数方法调用协议中引入特殊语法。
String[] words = {"hello", "world"}; print(words); //pass a single String[] print(words...); //pass two Strings String[]? words2 = first(words); //infers T = String[]; String? word = first(words...); //infers T = String
我认为这读起来相当自然。缺点是它是一种特殊用途的标点符号,需要在规范中特别解释。
解决方案2
第二个解决方案是引入一个特殊类型(一个子类型)来表示一系列序列化参数的包。称之为序列SequencedArguments。然后,通过一个包装的辅助方法spread(),语法将类似于序列这稍微有点冗长,但合理。这也使得编写规范更容易。。然后,通过一个包装解决方案3
String[] words = {"hello", "world"}; print(words); //compiler automatically produces a SequencedArguments<String[]> print(spread(words))); //explicitly pass a SequencedArguments<String> String[]? words2 = first(spread(words)); //infers T = String[]; String? word = first(spread(words)); //infers T = String
解决方案1和2可以非常优雅地结合。我们可以定义
T...
表示
- SequencedArguments
对于任何类型T,e... - 表示对于任何类型SequencedArguments(e)对于任何表达式e
所以SequencedArguments
我认为这是可行的,并且非常符合语言的精神。另一方面,如果SequencedArguments
void print(Object... objects, OutputStream stream) { ... } //compile error?
你的看法呢?print(words...)对于你们来说读起来怎么样,或者它感觉是任意的吗?
附言:
不要将这个与将操作应用于功能语言和动态语言中的参数元组的思想混淆。这表面上很相似,但并不完全相同。
更新:
一种合理的语法变化,可能读起来更好,可以使用所有作为一个关键字
void print(Object all objects) { ... }
print(words); //pass a single String[] print(all words); //pass two Strings
如果我不是那么讨厌将非常有用的单词“所有”变成关键字,我可能会接受这个。