English 简体中文 繁體中文 한국 사람 日本語 Deutsch русский بالعربية TÜRKÇE português คนไทย french

简体中文 繁體中文 English 日本語 Deutsch 한국 사람 بالعربية TÜRKÇE คนไทย Français русский

回答

收藏

Tact 语言基础 |结构(Structs)和消息(Messages)

开源社区 开源社区 7041 人阅读 | 0 人回复 | 2025-03-26

Tact 支持许多专为智能合约使用而定制的 原始数据类型。 不过,使用单独的存储方式往往会变得繁琐,因此有 Structs 和 Messages可以将类型组合在一起。 不过,使用单独的存储方式往往会变得繁琐,因此有 Structs 和 Messages可以将类型组合在一起。
8 I5 v5 T" i$ j! ^' h1 p3 W/ @3 O/ K% ^7 b+ A+ }
9 v4 _! z( L4 Z. Y1 B& |

6 |- a! Z: n: |4 g  {; U& m* w% h结构
& I8 \2 A, v+ H0 O/ I" }, g$ ?结构体可以定义包含多个不同类型字段的复杂数据类型。 它们还可以嵌套。 它们还可以嵌套。
. ~4 ^/ n8 `" `5 g
  1. struct Point {
    6 x5 h5 A+ ~( D# k/ l5 G
  2.     x: Int as int64;$ c* p, w; q# k, O$ y1 `* P9 j* ?
  3.     y: Int as int64;
    : N4 j+ A0 @; w
  4. }
    ) {% |- `: X; [- A

  5. 4 c+ D& M* V6 t$ m
  6. struct Line {& d  c4 o2 V: Q2 p2 f
  7.     start: Point;
    5 y* Q. f( P- [& n
  8.     end: Point;
    : Q0 m; g) g" I& h% M1 ~$ Y* e
  9. }
复制代码
结构体还可以包含默认字段,并定义可选类型的字段。 结构体还可以包含默认字段和定义[可选类型]字段(/book/optionals)。 如果您有很多字段,但又不想一直在 new instances 中为它们指定通用值,那么这将非常有用。
: L" c' s( u$ p& Z
  1. struct Params {
    1 ?7 E" d2 ]& P9 j0 ~
  2.     name: String = "Satoshi"; // default value
    # i9 r  I+ n8 s* ~# U, z/ }
  3. # O, G6 P5 U' i. q. f6 Q; B
  4.     age: Int?; // field with an optional type Int?, a/ _  y& k; s' J- u( z4 \& u
  5.                // and default value of null) l9 T1 q( t4 x. \0 P' X
  6. * @- ]- z8 S, e3 q1 `7 ^
  7.     point: Point; // nested Structs
    2 f& L/ j4 e1 U3 Z
  8. }
复制代码
字段的顺序很重要,因为它与TL-B 模式 中的内存布局一致。 不过,与某些采用手动内存管理的语言不同,Tact 在字段之间没有任何填充。% [3 j) M1 f: Q$ r$ |$ l
. W3 H; G9 ]- P( R5 {

  v  |+ y! B+ j+ U: }# \  N$ x, ^7 S
消息
6 a9 p0 m; a* P6 f消息中可以包含 结构体:$ p& J* W4 ~* }3 j6 D
  1. struct Point {7 u  {$ ^  L0 [, x, q
  2.     x: Int;' R2 L/ H8 V  _8 _6 H/ u
  3.     y: Int;
    8 U: n1 P1 ?$ K+ A
  4. }' g; t+ C! s9 p7 x

  5. ( t5 K+ E9 x  R% Q/ D% }
  6. message Add {
    ' G; g" A  B; z% g
  7.     point: Point; // holds a struct Point
    ' ^1 C# f0 L2 y% q4 f# d
  8. }
复制代码
  1. // This Message overwrites its unique id with 0x7362d09c* H, _: l, c) K" x7 f
  2. message(0x7362d09c) TokenNotification {
    % [1 ?# [3 j# \0 ?) u" v8 A
  3.     forwardPayload: Slice as remaining;
    - C3 t. t0 W: z
  4. }
复制代码
这对于要处理特定智能合约的某些操作码(如 Jetton standard)的情况非常有用。 该合约能够处理的操作码简表为此处以 FunC 表示。 它们是智能合约的接口。
6 w  w1 U1 a6 o6 s+ f% h! C9 D# L1 x, u( r

, O6 w2 J! c4 m( B3 ?操作
! a. \9 Z3 [' k8 d& e# |实例化
0 s4 G/ H" ^4 |: ^& l# `& u& ]创建 Struct 和 Message 实例类似于 function calls,但需要用大括号 {}(大括号)代替小括号 ()指定参数:
7 q' Z; }! C7 z
  1. struct StA {
      f' A" X1 q+ m, B; `' p' {& e1 ^
  2.     field1: Int;
    % I+ b5 y: `" h( X0 t
  3.     field2: Int;
    " `- _3 d, v1 t2 K. y+ e
  4. }- E6 x" @. a" B' J5 j" ?2 _
  5. % G2 ]% S1 k! s. ]9 r  L
  6. message MsgB {
    ( B( Y2 y/ ?9 h
  7.     field1: String;
    ; S% R& a; @  ?: L: ?% Z
  8.     field2: String;
    * v" j6 I3 f9 v  U' I. }
  9. }& O" ?5 V, B# u1 c

  10. 2 w9 s" X) f0 M2 {) `; u3 m
  11. fun example() {; H  P$ \" Q% U' I5 C" J
  12.     // Instance of a Struct StA. k. d; t  x: Y4 I3 [6 s
  13.     StA{
    7 J% U) h4 L0 i
  14.         field1: 42,
    + p$ u% s& n& }6 ^5 B) P7 e
  15.         field2: 68 + 1, // trailing comma is allowed) l4 O& ?3 K5 F/ [7 l% s4 i, ^
  16.     };
    ' I, e/ A# y1 x% o0 t
  17.   h5 f- ?7 r' O& \3 Z& f
  18.     // Instance of a Message MsgB
    , W) r2 U1 y, g- n
  19.     MsgB{
    / M! _2 F" ~7 g4 U
  20.         field1: "May the 4th",
    4 x$ W: H- M, q) O: l/ h4 J
  21.         field2: "be with you!", // trailing comma is allowed; R5 Q  N; g' \
  22.     };
    + B2 G8 W5 \0 ~- [- y
  23. }
复制代码
  1. struct PopQuiz {  {% [' ]2 a+ V6 O5 Y; y6 k0 L" u
  2.     vogonsCount: Int;+ X! t% m% q) T" F
  3.     nicestNumber: Int;1 g' ~2 @/ ^. B/ n7 F
  4. }
    & m) \) l& L  A1 `

  5. # M6 T6 w* p* ~6 f
  6. fun example() {' J+ }* m4 j4 q( u: g2 i
  7.     // Let's introduce a couple of variables
    ) u7 d/ ?( t0 q+ Z8 W  ~
  8.     let vogonsCount: Int = 42;
    8 r0 j) q* O* j0 J4 T" c
  9.     let nicestNumber: Int = 68 + 1;8 X2 S( s- |# Z. g* s. y( D7 s" U

  10. 4 h8 w( S  t6 u' V
  11.     // You may instantiate the Struct as usual and assign variables to fields,
    . f* O; T/ z4 j- O
  12.     // but that is a bit repetitive and tedious at times; i) B# s3 i6 G$ h
  13.     PopQuiz{ vogonsCount: vogonsCount, nicestNumber: nicestNumber };
    5 {1 B9 x9 c4 L5 R3 S2 v

  14. # g5 \9 r! @! v! o! i+ v
  15.     // Let's use field punning and type less,. l, r; k: B9 e& {" N2 Q9 s1 ?
  16.     // because our variable names happen to be the same as field names4 N) e1 I. l1 \
  17.     PopQuiz{8 k1 P6 e2 E, l( u* G+ O3 M
  18.         vogonsCount," o; p# b" S/ E& x6 V! [! b4 f
  19.         nicestNumber, // trailing comma is allowed here too!2 T3 Q! u+ m% c2 S/ h/ y4 A. v
  20.     };, B; D& ^/ U) o) v' T* }. I
  21. }
复制代码
  1. struct Big {* @* o/ H4 }$ j, W5 a
  2.     f1: Int;
    5 h6 k: [# f0 l3 D! l
  3.     f2: Int;4 u* R% ]5 R% r: i/ U8 V
  4.     f3: Int;' S# H+ y8 H. e3 ~. k5 O
  5.     f4: Int;9 V- c$ y, t9 d& `( v) d$ q
  6.     f5: Int;
    ) c5 R$ z+ q  l; v  ?6 y
  7.     f6: Int;& I/ E5 W- q4 A
  8. }6 S7 e8 a! s9 C# B; K- G* w
  9. / B, ?. [  B* c- u/ @, `. f0 ~- I
  10. fun conversionFun() {2 O% m, F2 {$ b2 `- h
  11.     dump(Big{; R& E: \6 E) c: U
  12.         f1: 10000000000, f2: 10000000000, f3: 10000000000,* T* n/ i) ?# l4 J! U! N/ V
  13.         f4: 10000000000, f5: 10000000000, f6: 10000000000,, U9 g) ]! W0 w  `
  14.     }.toCell()); // x{...cell with references...}# a( _. F" T2 o6 Q5 C# L% p
  15. }
复制代码
  1. struct Fizz { foo: Int }' S1 G! H8 ]& o, ?0 R, g; M/ W  G
  2. message(100) Buzz { bar: Int }
    4 T3 s( K/ k1 A% w  B- p! {

  3. # U% [9 m& k& _1 ]- c$ }
  4. fun constructThenParse() {
    ! F* E/ d6 L- G- I
  5.     let fizzCell = Fizz{foo: 42}.toCell();& @" g  N! j/ N
  6.     let buzzCell = Buzz{bar: 27}.toCell();! v; U* K/ I& v' \
  7. 2 T5 J: ?$ }. e4 f4 E+ F9 `1 n- X/ f, E
  8.     let parsedFizz: Fizz = Fizz.fromCell(fizzCell);# T1 ~, j: e4 V9 O+ C& _; P
  9.     let parsedBuzz: Buzz = Buzz.fromCell(buzzCell);1 P5 g- j7 V( A+ k# N
  10. }
复制代码
  1. struct ArbitraryStruct {}' |# h# B/ p0 s4 i7 ^
  2. message(0x2A) ArbitraryMessage {}
    ! F# t. i* E1 `8 s! y  t
  3. $ f0 J& o) _* Q+ B- Z+ X# x
  4. fun lawOne() {
    # c' R0 ], W) b" [8 F6 I
  5.     let structInst = ArbitraryStruct{};7 w, }/ B6 W; [$ {
  6.     let messageInst = ArbitraryMessage{};
    7 ^' a8 S' a, C- ]9 z( j

  7. ; d) z" Y' z  X8 o
  8.     ArbitraryStruct.fromCell(structInst.toCell());   // = structInst& ?+ D/ d4 m1 v7 d1 f4 |! ^' Y
  9.     ArbitraryMessage.fromCell(messageInst.toCell()); // = messageInst
    6 {% r/ h9 r& }5 T; u1 s! W4 |6 ^

  10. ( K# T% y, X  [3 F/ ^
  11.     // Same goes for Slices, with .toCell().asSlice() and .fromSlice()
    ! f7 G  x& w, b, w
  12. % v# k' W. @. V; D9 W
  13.     ArbitraryStruct.fromSlice(structInst.toCell().asSlice());   // = structInst. @/ {& g" C8 V3 }7 S
  14.     ArbitraryMessage.fromSlice(messageInst.toCell().asSlice()); // = messageInst
    9 g% L1 f8 T7 _$ Z& L  l( }
  15. }
复制代码
对于任何与给定 Struct/Message 具有相同 TL-B 布局的 cell,调用 Struct.fromCell()(或 Message.fromCell()),然后通过 .toCell() 将结果转换为 Cell,就会得到原始 cell 的副本:
  1. struct ArbitraryStruct { val: Int as uint32 }
    " }6 {( |9 l2 U2 q
  2. message(0x2A) ArbitraryMessage {}- g6 Q5 t- K4 }" @' f
  3. % l0 j+ m6 p9 F; k8 r/ I. H
  4. fun lawTwo() {
      z! p7 n1 w% l7 |5 J  J
  5.     // Using 32 bits to store 42 just so this cellInst can be. L1 Y5 a$ @- O# b9 `, _% j# J2 \/ F
  6.     // re-used for working with both ArbitraryStruct and ArbitraryMessage. H" q6 t# q+ Y! R3 U
  7.     let cellInst = beginCell().storeUint(42, 32).endCell();5 {( t4 Y4 A7 W& r; {
  8. ! s. f/ O; d* R3 \0 ^
  9.     ArbitraryStruct.fromCell(cellInst).toCell();  // = cellInst
    # e. G" B, t0 k) S; W# }
  10.     ArbitraryMessage.fromCell(cellInst).toCell(); // = cellInst( Y( ~' a( a, Z; E8 z

  11. % W, p- x9 b& B( v
  12.     // Same goes for Slices, with .fromSlice() and .toCell().asSlice()
    3 ]$ y% B) [6 i( q
  13.     let sliceInst = cellInst.asSlice();
    : `1 B' D! |! ^$ D2 v" S0 a

  14. " S. Z' x! \$ ]
  15.     ArbitraryStruct.fromSlice(sliceInst).toCell().asSlice();  // = sliceInst
    0 P+ s7 e" a3 g3 F& a+ i! a* D
  16.     ArbitraryMessage.fromSlice(sliceInst).toCell().asSlice(); // = sliceInst
    7 o* @9 t7 k8 \/ B2 w9 z! W
  17. }
复制代码

) F5 \: y/ w1 O. d: }/ M7 V
分享到:
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则