许多编程语言已经具有复合语句+=
,-=
,/=
等。一种相对较新的编程方式是将方法调用“链接”到彼此,例如在Linq,JQuery和Django的ORM中。
我有时候,经常发现需要在Django中执行此操作:
# Get all items whose description beginning with A
items = Items.objects.filter(desc__startswith='A')
if something:
# Filter further to items whose description also ends with Z
items = items.filter(desc__endswith='Z')
我认为如果有一个复合方法调用语句(例如.=
可以这样工作,那么它会更容易,实际上更具可读性:
items = Items.objects.filter(desc__startswith='A')
if something:
items .= filter(desc__endswith='Z')
答案 0 :(得分:2)
Perl 6支持此功能。
答案 1 :(得分:1)
恕我直言,我不喜欢它。
想象一下,
items .= click(function(){...});
它不再是语法错误,但它没有意义,是吗?
我可以说它没有意义,因为如果你扩展我的例子,它会是这样的,
items = items.click(function(){...});
items.click(function(){...});
只会返回对象items
,您会将其分配给items
?
在这个例子中,
items .= filter(desc__endswith='Z');
它会有意义,但并不适用于所有对象,也许这就是它没有实现的原因。
至于parent .= children();
,parent
稍后代码会发生什么?
我说的是jQuery方式。
答案 2 :(得分:1)
我无法回答这些问题,而且我不确定我对此的看法,因为我以前从未见过它,但确实有一个有趣的应用:所有的现场操作员都已经过时了。
a = 1
a .= __add__(1)
a .= __mul__(2)
当然,编写a += 1
更清楚,但如果语法设计中的语法较早,__add__
方法不那么难看(例如add
),今天的语言今天可能只有 11个更少的运营商。
(当然,还会有其他含义 - 尤其是从__iadd__
到__add__
的自动回退将会丢失。但这仍然是一个有趣的概念。)
答案 3 :(得分:0)
Scala的集合支持就地操作,前提是该变量为var
。
scala> var L = List("b", "c")
L: List[java.lang.String] = List(b, c)
scala> L ::= "a"
scala> L
res8: List[java.lang.String] = List(a, b, c)
(对于那些不熟悉Scala的人,::
是一种List
的方法
这是许多人避免的编程风格,在Scala中,您可以通过使用不可变val
来避免这种就地突变:
scala> val L = List("b", "c")
L: List[java.lang.String] = List(b, c)
scala> L ::= "a"
<console>:7: error: reassignment to val
L ::= "a"
答案 4 :(得分:0)
在进行Java或C#编程时,我经常考虑过这种情况,在这种情况下,你发现自己不仅重复了一个,而且在赋值的两边经常使用相同的两个或更多个对象引用 - 例如,你有一个对象的成员这是一个字符串,您希望在该字符串上调用一些方法并将其分配回成员变量。奇怪的是,它在Python中几乎没有让我感到困扰。
你提出的.=
运算符是我在做C#时想到的一个想法。另一种选择是允许前导点作为被分配对象的简写,如下所示:
foo.bar.str = .lower() # same as foo.bar.str = foo.bar.str.lower()
Pascal,Modula-2和Visual Basic有一个with
语句(不同于Python的同名语句),如果它存在于Python中,你可以编写类似这样的语句(我称之为“使用“这里没有错误的有效Python):
using foo.bar:
str = str.lower() # same as foo.bar.str = foo.bar.str.lower()
当你要对一个对象的成员进行大量操作时,这非常方便,因为它允许一个块。但是,您仍然具有一定程度的冗余,如果您将最后两个想法合并在一起,则可以将其消除:
using foo.bar:
str = .lower()
在我看来,这似乎是一个很好的语法糖,我发现它非常易读,但它似乎并不像大多数语言设计师的优先级列表。但是,由于Python确实具有Modula-2影响,因此最终可能会添加它并不是不可能的。
答案 5 :(得分:0)
Ruby在某种程度上具有此功能,但以不同方式实现它。这是通过'破坏性'方法,改变它们被调用的变量。例如,调用str.split只返回对象split,它不会改变它。但是,如果你打电话给str.split!它改变了它。大多数内置数组和字符串方法都具有破坏性和非破坏性版本。