Lambda 变量名称 - 简称,还是不简称? [关闭]
Posted
技术标签:
【中文标题】Lambda 变量名称 - 简称,还是不简称? [关闭]【英文标题】:Lambda variable names - to short name, or not to short name? [closed] 【发布时间】:2010-10-01 09:41:24 【问题描述】:通常,当我使用 lambdas 时,我只使用“a、b、c、d...”作为变量名,因为类型很容易推断,而且我发现短名称更容易阅读。这是一个例子:
var someEnumerable = GetSomeEnumerable();
var somethingElseList = someEnumerable.Select(a => a.SomeProperty)
.OrderBy(a => a.SomePropertyField);
var someDictionary = somethingElseList.ToDictionary(a => new SomeClass(a.Prop1),
a => a);
有人质疑这个命名,并希望看到长打出来的名字,像这样:
var someEnumerable = GetSomeEnumerable();
var somethingElseList = someEnumerable.Select(importantObj => importantObj.SomeProperty)
.OrderBy(objsInfo => objsInfo.SomePropertyField);
var someDictionary = somethingElseList.ToDictionary(theInfoId => new SomeClass(theInfoId.Prop1),
theInfoId2 => theInfoId2);
由于范围很窄(在括号之间),除非您变得愚蠢并嵌套它们,否则我发现阅读短名称更容易。
不要陷入我上面使用的愚蠢的命名示例,关于 Lambda 变量名称的普遍共识是什么?简称,还是不简称?
【问题讨论】:
【参考方案1】:我通常这样做的方式取决于您枚举的集合。如果集合的名称暗示 lambda 参数将是什么类型,那么我只使用单个字母,但是如果集合不是描述性的,那么我将使用一个词。
IE:
myCollection.Where(person =>....); //non descriptive collection name
myPeopleCollection.Where(p=>...); // descriptive collection name
【讨论】:
【参考方案2】:我尝试使用单字但有意义的名称。所以我倾向于使用“person”而不是“p”,但不会使用“newlyAddedPerson”。
这也适用于查询表达式 - 我可能会在快速的一次性示例中违反这一点,但我通常不喜欢:
from p in source
where p.Age > 10
select p.Name;
我宁愿看到
from person in source
where person.Age > 10
select person.Name;
【讨论】:
是的,我倾向于在表达式语法中命名更好,但那是因为范围更广,并且可能会变得混乱。 在表达式语法中,我通常命名更长的名称,因为范围更广。我看不出写 .OrderBy(theInt => theInt) 而不是 .OrderBy(a => a) 的意义。 它使查询的那个点的元素是什么更清楚。不幸的是,这并不总是显而易见的。【参考方案3】:我喜欢简称。我一直这样做。我主要在 lambdas 中使用 i,y,x,但我在 sql 中使用 a,b,c,d。
【讨论】:
【参考方案4】:我们的团队不允许单字母变量,不允许 lamdas 中的事件。
我们发现,就像在 TSQL 中一样,代码存在的时间越长,它就越混乱。至于 lambda 的
我们会这样做:
people.Where(personFound => personFound.FirstName.Contains("blah!"));
这样下一个开发者就不用看
people.Where(p => p.FirstName.Contains("blah"));
它似乎可读,但一开始总是这样
加盟怎么样
citizenShip.Join(people, c => c.personid, p => p.persoinid, (p, c) => new p.FirstName, c.IsCitizen)
.Where(pc => pc.FirstName.Contains("blah");
与变量名相同
citizenShip.Join(people,
citizenToJoin => citizenToJoin.personid,
personToJoin => personToJoin.persoinid,
(joinedPerson, joinedCitiznship) =>
new joinedPerson.FirstName, joinedCitiznship.IsCitizen)
.Where(personAndCitizenshipFound=> personAndCitizenshipFound.FirstName.Contains("blah");
哦,但这是令人困惑和丑陋的。只需使用不同的字母,以免混淆
citizenShip.Join(people,
c => c.personid,
p => p.persoinid,
(jp, pc) =>
new jp.FirstName, jc.IsCitizen)
.Where(pc => pc.FirstName.Contains("blah");
仍然令人困惑,但现在更糟了。所以我们将 lambda 分解,以便我们重构可读性
var peopleWithCitizenship = citizenShip.Join(people,
citizenToJoin => citizenToJoin.personid,
personToJoin => personToJoin.persoinid,
(joinedPerson, joinedCitiznship) => new joinedPerson.FirstName, joinedCitiznship.IsCitizen);
var peopleWithCitizenshipFilteredByName = peopleWithCitizenship.Where(personAndCitizenshipFound=> personAndCitizenshipFound.FirstName.Contains("blah"));
这不是一个完美的例子,但只需很少的内部知识就可以使代码可读。我们发现这暴露了复杂的代码(lambda),需要将其分解成更小的块。
【讨论】:
哦。当我们从其他代码中的单字母变量移开时,单字母的所有参数都是相同的。您所要做的就是查看一些带有一堆单字母别名的 TSQL,或者是开发人员坚持编写的带有一堆连接和选择的 lamda。【参考方案5】:我会说我同意 BFree。对我来说,这将取决于上下文,但我总是尽量让它尽可能“简洁”。请注意,我说的是简洁,而不是简洁或简短。
这是 LISP 方言 Clojure 中的两个示例:
user=> (def names ["ryan" "bob" "tom" "tim"])
#'user/names
user=> (filter (fn [name] (.startsWith name "t")) names)
("tom" "tim")
对于那些不了解 Lisp/Clojure 的人,我的 lambda 是函数“filter”的参数。也就是说,“(fn [name] ....)”。我在这里选择使用“名称”,因为它很短,但准确地描述了我正在使用的内容。但是,我认为 'a'、'i'、'x' 等同样具有可读性。
user=> (def odds (iterate (fn [n] (+ n 2)) 1))
#'user/odds
user=> (take 5 odds)
(1 3 5 7 9)
在这里,我只是用“n”来代表“数字”。我认为“数字”也可以,但对我来说有点过于冗长了。
我当然不会使用名称“nameOfPerson”或“previousOddNumber”。这只是太多的信息。大多数时候我也尽量不让类型出现在我的名字中,例如'名称字符串'。在大多数情况下,我发现这样的东西是多余的信息。
就我个人而言,我认为像这样更冗长的名称往往源于它有助于记录代码的想法。它似乎在 Java/C# 等语言中尤为普遍。我认为这可以双向争论,这取决于程序员的风格。但是,名称越冗长,代码就越紧凑(读起来越脆弱)。如果我的名字很具体,而且它的功能经常改变,那么名字很可能也必须改变很多。最终,DEV 可能会变得懒惰,您最终会得到一个实际上并不能描述变量用途的名称。这不是问题,当且仅当程序员不认为名称是正确的。诚然,这可能会在编译过程中很快解决(因为程序员会尝试分割两个字符串或类似的东西),但它可能会浪费时间并在较大的项目中造成混乱。
由于屏幕空间,我还主张简洁。我仍然尝试以 80 列宽包装我的行,而使用“myVaraibleNameIsAsLongAsAParagraph”时这很难。
最终,我认为它总是会归结为妥协。所以他们不喜欢“a”,但也许他们会同意你应该争取像“人”或“数字”这样的单字名称,并避免那种糟糕的驼峰式。
对不起这本书。
【讨论】:
【参考方案6】:就“命名”提出“共识”问题可能会要求很多。 :)
我同意“好名字的重要性”与名字的范围成正比。 Jon Skeet 的首选答案
from person in source ...
很有说服力,但如果名称被大量使用,特别是如果输入的名称更好,我想我更喜欢
from p in persons ...
【讨论】:
我看到质疑表达式语法中的命名与 lambda 语法中的命名不同。【参考方案7】:我选择一个、两个或三个字母,它们构成了所讨论对象的缩写。
Persons.Where(p => ...)
AnalysisCode.Where(ac => ...)
【讨论】:
【参考方案8】:作为一般规则,我认为变量/对象/方法名称越明确越好。由于我们经常将大部分时间花在阅读其他人的代码上,我们越容易理解,您就越能更快地将注意力从语法转移到逻辑上。如今,有了 IntelliSense 等,只要有可能,在清晰度方面犯错并不是真正的负担。
【讨论】:
【参考方案9】:基于上述答案,我认为普遍的共识是,如果您无法从上下文中分辨出您正在处理的内容,那么使用描述性名称会更好。例如:
entities.Where(person => person.Age >= 21);
然而,在上下文显而易见的情况下,单字母名称实际上可能有助于提高可读性,因为它可以更容易地关注关键信息。例如:
people.Where(p => p.Age >= 21);
或 people.Where(x => x.Age >= 21);
问题是,p
或 x
哪个更好?
p
,这是 SQL 查询中熟悉的模式,并提供一点额外提醒,提醒您正在谈论的是 Person
。
支持x
,如果您将Person
重命名为Customer
,您不必担心修复所有的lambda 参数。如果你使用了p
,如果你的代码变成customers.Where(p => p.Age >= 21)
,实际上会有点混乱,而x
基本上是不可知的。
我最近开始使用x
,到目前为止,我还没有发现任何明显的缺点,但如果您不同意,请发表评论。
【讨论】:
【参考方案10】:我同意@Johnny Wey;命名你的变量 - 出于同样的原因,你在任何其他代码中命名它们!不要仅仅因为代码的“内联”性质而理解这种偏离清晰的预设。可读性是关键——一目了然/无需“悬停”在东西上;否则,您不妨说不需要适当命名变量。如果与“Enuerable”一起使用可能会有一点余地,但仍然很高兴看到(再次一目了然)代码在做什么。如果变量类型推断依赖于传递给类或其他东西的一些泛型类型,来吧,命名它。让所有代码读起来像一个句子;计算机应该适应我们(“人性化”),而不是相反,我们开始像计算机一样行事并变得神秘,只是因为当我们这样做时我们可以/感觉更聪明/更像技术极客(诱惑就在那里,我知道!)。输入一个清晰的名称很容易,并且您仍然拥有在命名方法中执行的所有智能感知/句子完成选项。另外,悬停在 lambdas 的情况下并不总是为您提供有关 var 的信息(在调试期间令人沮丧),因此很高兴看到“足够清晰/具有代表性”的命名,尤其是对于尚未通过所有心理体操的新开发人员能够通过遍历语句上下文来推断类型(也可以是神秘的)。
【讨论】:
【参考方案11】:如果变量的目的明确,则缩短会更好。 Lambda 需要一种函数式的写作风格,因此您会在一行中看到很多链接。当你保持它们简短时,它会更清晰。
另一种情况是,有时您需要声明一个在该范围内没有相关性/意义的虚拟变量。在这种情况下,我使用_
,这对我来说很清楚。这很方便,尤其是在方法重载期间,例如,
public Foo Do()
return Do(_ => true);
public Foo Do(Func<T, bool> pattern)
return SomethingElse(pattern);
【讨论】:
以上是关于Lambda 变量名称 - 简称,还是不简称? [关闭]的主要内容,如果未能解决你的问题,请参考以下文章