我有对象,我只想根据不同的标准向访问者显示这些对象。该对象有一个位掩码,我定义了以下条件:
const FLAG_ALWAYS = 0; // always show this item
const FLAG_LOGIN = 1; // only display to logged in users
const FLAG_NOTLOGIN = 2; // only display to users not logged in
const FLAG_OTHER = 4; // other criteria
const FLAG_NORTH = 8; // GeoIP
const FLAG_SOUTH = 16;
标志的组合当然是可能的,如1+4+16
或2+4
。
一个项目可以在3种登录条件下显示,例如:已登录、未登录或两者兼有。因此我需要FLAG_NOTLOGIN
。
我被FLAG_ALWAYS
弄糊涂了。。。它应该是0
,还是应该覆盖像4095
这样的所有其他标志?
还是应该删除FLAG_NOTLOGIN
?
答案取决于如何组合标准。有两种最简单的情况。
任何匹配或组合您设置的任何标志都将添加匹配项,越多的标志越多的匹配项。
在这种情况下,所有重置标志(0x0000)将永远不匹配。这意味着不符合任何标准。
设置的所有标志(0xFFFF)将导致大多数匹配。如果您有互补的标准(其中一个已设置),则标准将始终匹配。
Match是这样实现的:0!=(filter & criteria)
其中CCD_ 9是要过滤的标准的集合,而CCD_。
所有匹配,AND组合您设置的任何标志都会过滤掉一些匹配项,更多的标志会过滤掉更少的匹配项。
在这种情况下,所有重置的标志将始终匹配。
设置的所有标志将导致最少的匹配。如果您有互斥条件(一个设置,然后其他重置),则所有条件都将导致不匹配。
E。g.你的旗帜:FLAG_LOGIN
、FLAG_NOLOGIN
。用户可能已登录,也可能未登录,因此永远不会满足BOTH条件,并且FLAG_LOGIN+FLAG_NOLOGIN
永远不会匹配,但0
在任何情况下都会匹配,因为没有设置任何条件。
使用以下公式实现匹配:0==(all_flags & ~filter & ~criteria)
,此处filter
和criteria
与上述相同,all_flags
由所有使用的标志组成,以排除比较中未使用的位。(注意,表达式criteria == (filter & criteria)
似乎更明显,但却是错误的,因为当在标准中没有设置标志时,它将导致不匹配)。
如果您的标志是1 | 4
,而对象具有1 | 8
,则第一种情况将匹配(因为满足1
标准,一个就足够了),而第二种情况将不匹配(不满足4
标准,但您需要1
和4
)。
FLAG_ALWAYS应该是所有其他标志的组合,并且不应该为零。FLAG_NOTLOGIN无需删除。