如何使用位/位运算符来控制对象状态?

发布于 2024-07-12 12:00:51 字数 1121 浏览 7 评论 0原文

我想创建轻量对象数据包以在客户端和服务器应用程序之间传递。

这是一个非常简单的任务,我只需 1 个字节即可控制,所以 字节中的每个位都有不同的含义,

0 = False 
1 = True

仅使用我现在需要的

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?

Itens: 解决方案

在所有帮助之后,我将使用下一个 Set

  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;

And 进行流 -> 坚持下去,这将是要使用的记录:

  TDataPackage = record
    Data: TBytes;
    TypeInfo: TMetaInfo;
    State: Byte;
    Instance: TBuffer;
  end;

谢谢大家的所有回答和评论。

I want to create light object data-package to pass between client and server applications.

It is a so simple task, that I can control with only 1 byte, so
each bit in a byte will have a different meaning,

Using only the bit

0 = False 
1 = True

Itens I need now:

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

After all help, Ill use the next Set

  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;

And for stream -> persistance, this will be the record to be used:

  TDataPackage = record
    Data: TBytes;
    TypeInfo: TMetaInfo;
    State: Byte;
    Instance: TBuffer;
  end;

Thank you guys, for all the answers and comments.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

灼痛 2024-07-19 12:00:51

我真的会为此使用一套。 不过,我发现你确实想要一个字节。 到处使用集合,然后最后类型转换为字节。

正如 Barry Kelly 指出的那样,该解决方案将需要更少的打字,支持标准的 delphi 运算符,并且实际上不会带来性能损失。

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;

I'd really use a set for this. However, I see you really want a byte. Use sets everywhere then typecast to a byte in the end.

This solution will require much less typing, has support for standard delphi operators and really carries no performance penalty as Barry Kelly has pointed out.

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;
牛↙奶布丁 2024-07-19 12:00:51

我会为此使用一个集合:

type
    TMyDatum = (mdLoaded, mdPersisted, mdChanged, mdMarkedToDelete, ...);
    TMyData = set of TMyDatum;

var
  Foo: TMyData;
begin 
  Foo := [mdLoaded, mdChanged];
  if (mdPersisted in Foo) then ...

它们被实现为整数,因此您可以轻松地传递它们。 我发现代码比按位运算符更具可读性。

I would use a set for this:

type
    TMyDatum = (mdLoaded, mdPersisted, mdChanged, mdMarkedToDelete, ...);
    TMyData = set of TMyDatum;

var
  Foo: TMyData;
begin 
  Foo := [mdLoaded, mdChanged];
  if (mdPersisted in Foo) then ...

These are implemented as integers, so you can pass them easily. And I find the code much, much more readable than bitwise operators.

悟红尘 2024-07-19 12:00:51

本页介绍了 Delphi 运算符,包括按位运算符。

听起来您需要使用 and 运算符。 例如:

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...

为了设置标志,您可以使用 OR:

bitFlags := LOADED_FROM_DATABASE or PERSISTED or CHANGED;

This page describes Delphi operators, including bitwise operators.

It sounds like you need to use the and operator. For example:

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...

In order to set the flags, you can use OR:

bitFlags := LOADED_FROM_DATABASE or PERSISTED or CHANGED;
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文