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

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

回答

收藏

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

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

Tact 支持许多专为智能合约使用而定制的 原始数据类型。 不过,使用单独的存储方式往往会变得繁琐,因此有 Structs 和 Messages可以将类型组合在一起。 不过,使用单独的存储方式往往会变得繁琐,因此有 Structs 和 Messages可以将类型组合在一起。
% U/ u( |# `. @  x- c* J6 s0 q4 @( P- w0 K4 n9 d  @

$ z/ s8 v. i: x% R7 X3 C$ V+ {+ ]* s/ ^: D# l( A# e0 P
结构8 ]0 Y& m6 R" ~' _
结构体可以定义包含多个不同类型字段的复杂数据类型。 它们还可以嵌套。 它们还可以嵌套。
* r; F7 N4 p7 `9 R) Z& C3 I- T  U8 \
  1. struct Point {
    / Z" s$ x6 _8 g" z3 u) s
  2.     x: Int as int64;! K/ J( I" `9 |* R& J
  3.     y: Int as int64;. n) v4 T( `: @( [9 C: A" Q
  4. }
    9 ~7 @5 `, I% v  o: h* z

  5. * K2 J) Q& s  e: q( Z% V+ b* V
  6. struct Line {
    2 Q$ U* H8 I% T! C' i) i$ _
  7.     start: Point;4 Z+ H3 ^3 J8 c/ D& M+ Y
  8.     end: Point;
    $ I) k. X' K) i8 {) r
  9. }
复制代码
结构体还可以包含默认字段,并定义可选类型的字段。 结构体还可以包含默认字段和定义[可选类型]字段(/book/optionals)。 如果您有很多字段,但又不想一直在 new instances 中为它们指定通用值,那么这将非常有用。
/ W- m/ ]. W( D1 g7 Q  J
  1. struct Params {
    3 ^' y2 [, J% e2 c0 l* P1 R
  2.     name: String = "Satoshi"; // default value7 z4 i0 ]9 m! i

  3. & r3 w. {: I- b9 ^8 b( @/ ]
  4.     age: Int?; // field with an optional type Int?2 u" [& I1 b: N( b8 ~$ F
  5.                // and default value of null' r% B( t0 g5 ]; T

  6. . R' l3 D7 J; f3 G+ Y8 {
  7.     point: Point; // nested Structs7 K+ k! j4 f( K( j7 X) y* x" S
  8. }
复制代码
字段的顺序很重要,因为它与TL-B 模式 中的内存布局一致。 不过,与某些采用手动内存管理的语言不同,Tact 在字段之间没有任何填充。
+ ^3 f1 Q! M) N& J" `; x+ O
+ V: F8 w: O, l3 b$ J" Z# P( v3 v+ k' ]+ V' i
8 |* h- K3 m8 K6 I! ?6 a& ]1 K$ \0 J7 Q7 c
消息6 c. T; j1 q1 q( g% U: Q2 J: a
消息中可以包含 结构体:% C/ H" U! |6 _: |2 ]! ~% L) c
  1. struct Point {3 d$ k3 z4 \9 W  ?
  2.     x: Int;& H7 F3 r' ~, w* L+ B
  3.     y: Int;
    6 j" b7 A' U, I0 V( q- l- v) v
  4. }
    6 p* c) I% J; O' K
  5. , U1 p( E2 Q" L, m3 P. E
  6. message Add {  O% b  m: i3 N/ I( I
  7.     point: Point; // holds a struct Point0 R$ }0 D# S3 p9 S; C
  8. }
复制代码
  1. // This Message overwrites its unique id with 0x7362d09c# F6 W) i) m  p* p7 _: Z
  2. message(0x7362d09c) TokenNotification {9 y8 |, T( v! m
  3.     forwardPayload: Slice as remaining;
    1 t# u0 x% Q* k  n8 M
  4. }
复制代码
这对于要处理特定智能合约的某些操作码(如 Jetton standard)的情况非常有用。 该合约能够处理的操作码简表为此处以 FunC 表示。 它们是智能合约的接口。  q1 [+ S7 h1 E  K5 m5 A& C3 S
$ j" ]' l$ b4 R8 M; ]# Y
1 D1 K  H9 K4 W" V7 F
操作
! b8 Q% y" s# s7 a. }实例化
% K* e' t0 _& L( a+ j% \2 ]2 `创建 Struct 和 Message 实例类似于 function calls,但需要用大括号 {}(大括号)代替小括号 ()指定参数:) S3 G6 F  O- H( @/ v. S/ F3 x: x
  1. struct StA {4 g" B: I! O" G: `
  2.     field1: Int;
    $ P/ \6 Y! k, F5 y. z% v
  3.     field2: Int;
    4 P/ P5 B) B( v9 H- J
  4. }
    # T1 Y- B* _, p4 r5 P
  5. 9 }& q: `* J' O/ c$ s" q
  6. message MsgB {
    8 N) b: R  ^( e4 M
  7.     field1: String;
    " ?" z6 c. A# q1 D  H
  8.     field2: String;
    ) R1 x2 p4 H% w: @5 D  i- I: E0 Y2 u
  9. }
    2 g4 p4 a7 N- E$ `5 @
  10. , ^' |- _" }6 M& B3 P
  11. fun example() {& i  t" E" ]8 R3 v1 J, w
  12.     // Instance of a Struct StA$ u, W; }& F3 r6 O- p
  13.     StA{; T+ C# q7 T/ F% K! @9 l% s
  14.         field1: 42,
    . G2 U9 ~2 J; H/ ?# Q
  15.         field2: 68 + 1, // trailing comma is allowed
    ! o5 v% u" U  u3 C, d" \
  16.     };
    - {- g. N3 h, R6 u( g

  17. / w: g. J/ `( ?4 l' ]: f; G
  18.     // Instance of a Message MsgB
    % h) T$ H. a0 q5 C
  19.     MsgB{6 |9 I6 |1 q  E, v: f( C
  20.         field1: "May the 4th",
    / Z- z! g4 {" E6 }, t" B- E" @( d
  21.         field2: "be with you!", // trailing comma is allowed
    " @: w0 B" |! u7 @6 n1 ~) z* j0 o
  22.     };
    . i) z4 V/ J$ H
  23. }
复制代码
  1. struct PopQuiz {, {* d- j, c, q
  2.     vogonsCount: Int;& T6 |* p$ k2 A
  3.     nicestNumber: Int;# Q+ i# a3 C! z
  4. }
    ) S8 p/ R$ T. \- s, M1 Q; s$ d% n

  5. 2 L/ g( Q" B. G
  6. fun example() {# O! g- c+ V9 M1 J4 a$ R0 t; E& Z
  7.     // Let's introduce a couple of variables7 }- v6 [/ I, Y6 _5 l
  8.     let vogonsCount: Int = 42;$ s& ], d) Y# r4 g+ q
  9.     let nicestNumber: Int = 68 + 1;
    " Z1 f9 Q/ U! P4 `! w
  10. 4 G4 ]. E& N4 m& [
  11.     // You may instantiate the Struct as usual and assign variables to fields,
    9 \1 I8 o& g$ x  J
  12.     // but that is a bit repetitive and tedious at times
    : b8 Q; d9 ~- h# f9 e
  13.     PopQuiz{ vogonsCount: vogonsCount, nicestNumber: nicestNumber };- y$ |6 l/ I. H5 d
  14. ( `- d/ x! }8 P  z5 B/ p. c
  15.     // Let's use field punning and type less,- I# G0 g$ P0 U& {. M
  16.     // because our variable names happen to be the same as field names
    - O" P, D6 _& Z3 j+ Q
  17.     PopQuiz{% c+ u' j" E. H9 S8 F( l5 |
  18.         vogonsCount,
    & B6 a. L5 Z* V1 Y% q5 E& l- F4 ?
  19.         nicestNumber, // trailing comma is allowed here too!" ~4 Y) ^+ y" z; d4 ~
  20.     };
    ) L& C" ^, ~! G
  21. }
复制代码
  1. struct Big {
    ( i) n$ ]4 {4 I* I$ U  Z
  2.     f1: Int;
    9 g. e+ @9 T* b; s6 l# @0 k) S
  3.     f2: Int;, q1 y* h# s, r7 A1 H4 @( b
  4.     f3: Int;- ~9 F& d# o# Y
  5.     f4: Int;
    + N! p' {; }9 B+ _9 o
  6.     f5: Int;
    ' O1 S& d' q: ^$ e
  7.     f6: Int;8 Z+ k) c& A/ e$ K' l! y
  8. }
    7 j% n( A! k$ m# [, R

  9. ; K4 `8 N& A$ o9 B
  10. fun conversionFun() {
    ; M; ]' w; M  `: a8 x6 A
  11.     dump(Big{
    4 f# z' e+ g1 o# y: X) m2 x' l
  12.         f1: 10000000000, f2: 10000000000, f3: 10000000000,
    0 h0 m3 @' P6 d; L& g/ ^
  13.         f4: 10000000000, f5: 10000000000, f6: 10000000000,
    8 s! _1 D- i1 L" }  S7 Z) j
  14.     }.toCell()); // x{...cell with references...}; S  D) |$ u$ B. j8 |' ?' s7 g
  15. }
复制代码
  1. struct Fizz { foo: Int }
    4 ~& e4 D9 {$ C6 b
  2. message(100) Buzz { bar: Int }/ V! w+ F/ \1 v/ r4 v. I  E5 V& Y: G

  3. * p; Q5 N) F, D" C# f$ A
  4. fun constructThenParse() {
    1 H. f, o1 G- o7 o" R) s- j6 X
  5.     let fizzCell = Fizz{foo: 42}.toCell();5 j: N& R% G$ \8 |4 g- A, |
  6.     let buzzCell = Buzz{bar: 27}.toCell();; t3 v( f0 ]( \4 f2 Y
  7. 9 w( X  }8 {5 l) C
  8.     let parsedFizz: Fizz = Fizz.fromCell(fizzCell);8 |0 i. s1 a4 W# X0 o& P
  9.     let parsedBuzz: Buzz = Buzz.fromCell(buzzCell);4 u* |( ~$ b4 E
  10. }
复制代码
  1. struct ArbitraryStruct {}+ P1 b2 F6 f  k- c" X7 e1 s2 D# `
  2. message(0x2A) ArbitraryMessage {}
    4 M7 O  k2 k/ c. Q/ s+ ]3 Q
  3. 7 X& t) d8 j, L3 Z7 e
  4. fun lawOne() {( P3 Y- \. @, H; S
  5.     let structInst = ArbitraryStruct{};
    : G- Z1 k4 C& E- W) O4 g
  6.     let messageInst = ArbitraryMessage{};
    0 Z+ V) S* z! h" L' F7 m- O

  7. * L) b/ k3 U9 k0 f) N- w! m+ C
  8.     ArbitraryStruct.fromCell(structInst.toCell());   // = structInst
    8 N! Z6 [4 e# D. L: ~$ g' B
  9.     ArbitraryMessage.fromCell(messageInst.toCell()); // = messageInst, V/ X) D2 a2 x6 q
  10. 2 ?+ y1 ?1 Z  y" ^9 m# }! T
  11.     // Same goes for Slices, with .toCell().asSlice() and .fromSlice()' O$ d/ x  e/ M8 u4 L; c

  12. 6 r- i' P$ O* N* |( B
  13.     ArbitraryStruct.fromSlice(structInst.toCell().asSlice());   // = structInst. U  b8 B: M2 ^2 ?$ z8 o9 x
  14.     ArbitraryMessage.fromSlice(messageInst.toCell().asSlice()); // = messageInst2 ?5 R$ I% w. x. d+ g
  15. }
复制代码
对于任何与给定 Struct/Message 具有相同 TL-B 布局的 cell,调用 Struct.fromCell()(或 Message.fromCell()),然后通过 .toCell() 将结果转换为 Cell,就会得到原始 cell 的副本:
  1. struct ArbitraryStruct { val: Int as uint32 }( [* y. z) d5 E, v  E, D$ I% S
  2. message(0x2A) ArbitraryMessage {}: I! [  F, z2 a" o/ K4 v) L# f
  3. . e6 l# Z7 K7 n5 W4 a8 R2 S
  4. fun lawTwo() {& M/ s# r& `" [4 D5 o* ~
  5.     // Using 32 bits to store 42 just so this cellInst can be
    ( N( _) Z8 `; I4 q0 Q
  6.     // re-used for working with both ArbitraryStruct and ArbitraryMessage
    / J- I  g* J+ h" @& a9 X$ P8 L
  7.     let cellInst = beginCell().storeUint(42, 32).endCell();( k/ Q  y$ W" k1 |

  8. 0 F/ n" x* z7 b- n  B: K# {
  9.     ArbitraryStruct.fromCell(cellInst).toCell();  // = cellInst0 M3 U) u" f) U" [; J* V4 j0 ^
  10.     ArbitraryMessage.fromCell(cellInst).toCell(); // = cellInst
    0 K+ a4 q; r4 R" _
  11. 1 e; |/ x& N) d6 h* l
  12.     // Same goes for Slices, with .fromSlice() and .toCell().asSlice(); g8 S9 f# z" z0 r- B
  13.     let sliceInst = cellInst.asSlice();- J+ @! s  u3 c

  14. & V/ ]9 |9 L) [. b' p5 x
  15.     ArbitraryStruct.fromSlice(sliceInst).toCell().asSlice();  // = sliceInst
    $ n/ o8 N: Z" g; o- a/ V, P
  16.     ArbitraryMessage.fromSlice(sliceInst).toCell().asSlice(); // = sliceInst/ b" w: P9 r- z1 e! C8 Q& R0 y7 m, h
  17. }
复制代码
0 U- v, a' B9 o- q
分享到:
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则