如何用Lua的and/or运算符简化赋值代码?现有代码问题求解
Let's start by aligning on your original logic to make sure we're working from the same baseline:
- When
leftistrueandrightisfalse:xPos = -1 - When
rightistrueandleftisfalse:xPos = 1 - When both are
trueor both arefalse:xPos = 0
Why Your Simplified Code Fails
Your attempt:
local xPos = right and not left and 1 or -1
Relies on Lua's short-circuit evaluation rules for and/or, which work like this:
a and b: Returnsaifais falsy; otherwise returnsba or b: Returnsaifais truthy; otherwise returnsb
Let's walk through every scenario to see where it breaks:
- left=true, right=false:
rightis falsy, soright and not leftreturnsfalse. Thenfalse or -1returns-1(this matches your desired logic). - left=false, right=true:
right and not leftevaluates totrue, sotrue and 1returns1. Then1 or -1returns1(this also works). - left=true, right=true:
right and not leftbecomestrue and false = false. Thenfalse or -1returns-1—but your original logic expects0here. - left=false, right=false:
rightis falsy, soright and not leftreturnsfalse. Thenfalse or -1returns-1—again, original logic expects0.
The core issue is your expression only handles two of the four possible state combinations. There's no branch that returns 0 for the "both true" or "both false" cases, so it defaults to -1 incorrectly.
Correct Simplifications
Here are a few clean, idiomatic ways to implement your logic with and/or (and other Lua tricks):
1. Explicit and/or Branching
This directly translates your original if-else chain into a single line, covering all cases:
local xPos = (left and not right) and -1 or (right and not left) and 1 or 0
How it works:
- First checks if
leftis true andrightis false: returns-1if so - If not, checks if
rightis true andleftis false: returns1if so - If neither condition is met, returns
0(covers both true or both false)
2. Arithmetic Shortcut (Most Clean!)
Lua treats true as 1 and false as 0 in arithmetic contexts, so you can calculate xPos directly with simple math:
local xPos = (right and 1 or 0) - (left and 1 or 0)
Or equivalently:
local xPos = (right and 1 or 0) + (left and -1 or 0)
Testing this against all cases:
- left=true, right=false:
0 - 1 = -1(correct) - left=false, right=true:
1 - 0 = 1(correct) - left=true, right=true:
1 - 1 = 0(correct) - left=false, right=false:
0 - 0 = 0(correct)
3. Readable Ternary-Style Check
If you prioritize clarity over brevity, you can first check if left and right differ, then return the appropriate value:
local xPos = left ~= right and (left and -1 or 1) or 0
This reads like: "If left and right are different, return -1 if left is true, else 1; if they're the same, return 0."
内容的提问来源于stack exchange,提问作者arsonist

