Comment utiliser le bit / bit-opérateur pour contrôler l'état de l'objet?
-
21-08-2019 - |
Question
Je veux créer un objet lumière des données package pour passer entre les applications client et serveur.
Il est une tâche si simple, que je peux contrôler avec seulement 1 octet, donc chaque bit dans un octet aura un sens différent,
En utilisant seulement le bit
0 = False
1 = True
Itens Je dois maintenant:
1 - Loaded from database
2 - Persisted
3 - Changed
4 - Marked to Delete
5 -
6 -
7 - Null Value
8 - Read Only
1) How do I use bit operators in Delphi to check each bit value?
2) How do I set the bit Values?
Solution
Après tout aide, Ill utiliser la prochaine série
TStateType = (
stLoaded = 0, // loaded from persistance
stNative = 2, // value loaded and converted to native type
stPersisted = 3, // saved
stChanged = 4, // object or member changed
stToDelete = 5, // marked to delete
stReadOnly = 6, // read only object, will not allow changes
stNull = 7 // value is null
);
TState = Set of TStateType;
Et pour le flux -> persistence, ce sera le dossier à utiliser:
TDataPackage = record
Data: TBytes;
TypeInfo: TMetaInfo;
State: Byte;
Instance: TBuffer;
end;
Merci les gars, pour toutes les réponses et commentaires.
La solution
Je voudrais vraiment utiliser un ensemble pour cela. Cependant, je vois que vous voulez vraiment un octet. Utiliser des jeux partout puis transtypé un octet à la fin.
Cette solution nécessite beaucoup moins de frappe, a un support pour les opérateurs standards et delphi porte vraiment pas de pénalité de performance Barry Kelly a souligné.
procedure Test;
type
TSetValues = (
TSetValue1 = 0,
TSetValue2 = 1,
TSetValue4 = 2,
TSetValue8 = 3,
TSetValue16 = 4,
TSetValue32 = 5,
TSetValue64 = 6,
TSetValue128 = 7
);
TMySet = set of TSetValues;
var
myValue: byte;
mySet: TMySet;
begin
mySet := [TSetValue2, TSetValue16, TSetValue128];
myValue := byte(mySet);
ShowMessage(IntToStr(myValue)); // <-- shows 146
end;
Autres conseils
J'utiliser un ensemble pour cela:
type
TMyDatum = (mdLoaded, mdPersisted, mdChanged, mdMarkedToDelete, ...);
TMyData = set of TMyDatum;
var
Foo: TMyData;
begin
Foo := [mdLoaded, mdChanged];
if (mdPersisted in Foo) then ...
Ceux-ci sont mises en œuvre sous forme d'entiers, de sorte que vous pouvez les passer facilement. Et je trouve le code beaucoup, beaucoup plus lisible que les opérateurs binaires.
Cette page décrit les opérateurs Delphi, y compris les opérateurs au niveau du bit.
On dirait que vous avez besoin d'utiliser l'opérateur. Par exemple:
const
LOADED_FROM_DATABASE = 1;
PERSISTED = 2;
CHANGED = 4;
// etc...
//...
if (bitFlags and LOADED_FROM_DATABASE) <> 0 then
begin
// handle LOADED FROM DATABASE
end;
if (bitFlags and PERSISTED) <> 0 then
begin
// handle PERSISTED
end;
// etc...
Pour définir les drapeaux, vous pouvez utiliser OU:
bitFlags := LOADED_FROM_DATABASE or PERSISTED or CHANGED;