Answers:
编写某些代码的惯用方式是当您以非常特定的方式编写代码时,因为其他语言没有特定于语言的习惯用法。
例如,在C ++中,利用RAII惯用语导致编写用于管理惯用资源的C ++代码的方法。
另一个示例是在Python中使用列表推导生成列表。这是惯用的,因为您会在惯用的Python中使用列表理解功能,但是您可以使用生成器函数以任何其他语言甚至在Python中完成列表理解。
通常,尝试使用新语言而不使用特定于该语言的习惯用法的人不会编写惯用代码。
TryAdd()
在Generic Dictionary
类上调用的扩展方法以首先检查!Contains()
然后调用Add()
,这会成语吗?我正在使用特定于C#的功能-扩展方法。
正常定义
使用,包含或表示母语使用者的自然表达
编程定义
使用,包含或表示[插入语言]程序员自然的表达式
编程上下文中的惯用语通常可以定义为“用某种语言表达某些内容的最自然方式”
我看到Ruby中惯用语这个词特别多。在Ruby中,具有大量的元编程功能,并且要编写惯用的Ruby代码,通常必须使用这些功能。
请注意,仅仅因为一段代码是惯用的,并不意味着它是干净的甚至简洁的。很多时候,您必须做出让步。
因此,从根本上说,惯用语最常见是指用某种语言写东西的最常见方式,通常包括“ s语”(成语)。如果一段代码不是惯用的,那么它可能会完全可读,简洁,整洁且正确,但是在使用的语言中可能会感到/看起来很尴尬。喜欢习惯性地重写这样一段代码是否真的是一件好事,并且必须根据具体情况进行判断,这是一种偏爱
例如,惯用英语可能取决于地区。bum
惯用的英国英语可能需要使用该词,而butt
对于美国英语则更合适。(可悲的是我对英国英语了解不多:/)
我能想到的最好的例子是Ruby,这是我惯用的东西。
在多种语言中,您可以进行以下迭代:
for( start; end; increment){
code;
}
或类似的东西。许多语言也有foreach(x in SetOfXes)
结构。但是,Ruby特有的迭代包括以下内容:
collection.each do |current|
current.do_stuff
end
乃至
10.times do |x|
puts x
end
我认为这些是惯用的,因为它们代表了一种不常见的方法,并且代表了其领域哲学的核心。Ruby的哲学是与对象进行交互,尽管这种交互不是唯一的,但并不普遍。
从语义上讲,每当我听到“惯用语”一词时,我的大脑就会自动将其构想为“惯于……”-我只是反身将其解析为与特定主题有关。
collection.each do |current|
不同foreach(current in collection)
?两者都是设置current
为的每个元素的循环构造collection
。
习惯用法通常是用一种语言表达一种常见的,相对复杂的情况的最佳方法。递增不是惯用语,也不是任何种类的东西。使用前缀增量而不是后缀,可以说是C ++惯用语。
根据专家用户的决定,习惯用法是使用一种语言的最佳方法。真正的C ++习惯用法就是函数对象。另一个惯用语是RAII。语言中没有任何内容告诉您必须释放析构函数中的资源。但这是惯用法。另一个例子是模板-可以使用模板做很多事,这是惯用的,但是没有什么可以阻止您过度使用继承。
您的定义不正确。习惯用法是一种书写某些其他语言可能或不可能的东西的方式,但这在该语言中很常见。通常,它比替代方法短,但这并不是必须的。
通过讨论非惯用语来解释它可能会更容易。在C ++中,编写代码很惯用:
Foo* p = SomeThingThatReturnsAFooPointer(arg, param, x, y);
if(p)
{
// whatever
}
编写起来更惯用:
Foo* p;
if(p = SomeThingThatReturnsAFooPointer(arg, param, x, y))
{
// whatever
}
这段代码的作用完全相同-一些C ++的新手可能会将它读为测试,以查看p是否等于该函数返回的值,但事实并非如此。
与可能来自另一种语言的某人(非常不习惯)所写的内容相比:
Foo* p = SomeThingThatReturnsAFooPointer(arg, param, x, y);
if(p !=NULL)
{
// whatever
}
您还将看到这些东西被敲成非惯用语:
if (x>0)
return true;
else
return false;
因为惯用的方法是
return (x>0);
非惯用的方法没错,但是对于那些习惯用语的人来说,它们的打字时间通常更长,阅读时间也更长。如果我称呼您为“哭泣的狼的男孩”,并且您知道这个故事,那么比我解释虚假警报如何导致人们无视您的情况要快。当然,问题是如果您不了解故事,也不知道狼与我们所说的事情有什么关系。同样,如果您以前从未见过return x<y;
并且真的不知道它会做什么,则可能会遇到问题。
if(Foo* p = SomeThingThatReturnsAFooPointer(arg, param, x, y))