|
Tact 支持许多专为智能合约使用而定制的 原始数据类型。 不过,使用单独的存储方式往往会变得繁琐,因此有 Structs 和 Messages可以将类型组合在一起。 不过,使用单独的存储方式往往会变得繁琐,因此有 Structs 和 Messages可以将类型组合在一起。
7 N: b( U, t( m* p
. p1 ~ |+ v6 ~( p9 r
( l* K9 z) `" ~% e7 A' k# h
" o7 S# z* D3 `6 u" Q" Y+ l结构
# Y) u* @+ {+ t结构体可以定义包含多个不同类型字段的复杂数据类型。 它们还可以嵌套。 它们还可以嵌套。
/ n& e+ y3 s! [# ` Q- struct Point {
1 D. V0 U% p1 D& v2 o - x: Int as int64;- h( f6 W6 T3 _& V
- y: Int as int64;
7 y1 d- v/ { }4 j+ K9 @ - }
7 e& F% x# ? t6 ?1 l# G
* n1 t- _! O8 K6 c( g( Z- struct Line {
9 j+ y ^7 s& w9 o. B `3 | - start: Point;
6 a# ~) B; n) k% A* [; Z - end: Point;
" h0 |! ~5 ]4 Q - }
复制代码 结构体还可以包含默认字段,并定义可选类型的字段。 结构体还可以包含默认字段和定义[可选类型]字段(/book/optionals)。 如果您有很多字段,但又不想一直在 new instances 中为它们指定通用值,那么这将非常有用。
8 H- e' F* m1 Z9 Q" r3 z; w- struct Params {
p8 c4 m$ Z. r; v7 ?9 C3 J - name: String = "Satoshi"; // default value# k: _: d8 u8 b' |# z: d
- + T1 K: K1 w: q" d/ }9 K
- age: Int?; // field with an optional type Int?
; C6 t' Y6 w% x8 P0 D# V - // and default value of null
/ e. k+ T6 C6 F6 p( i/ R- H) Y/ C
5 N4 b2 Y2 n: a- point: Point; // nested Structs
3 p7 ^4 ~/ t0 _# Z; ^; d; K - }
复制代码 字段的顺序很重要,因为它与TL-B 模式 中的内存布局一致。 不过,与某些采用手动内存管理的语言不同,Tact 在字段之间没有任何填充。
2 `, P/ k+ g1 w' N9 {; _
+ }2 m2 d2 L6 a- ]/ f- h, _3 F, I
& m. b9 Q4 T$ k
消息1 D' a6 N& }' Q, j; ?% {
消息中可以包含 结构体:
1 j3 }! O: C# L4 Y0 ?- struct Point {- K- E+ e( i* `
- x: Int;
+ l' A$ y0 ] K9 R6 P - y: Int;! T7 i; E d8 h
- }: ^. K% J0 F) ^" m6 g
- * d( O9 @0 \' p0 Z$ R
- message Add {8 _2 o- @6 k0 ?6 A1 d
- point: Point; // holds a struct Point1 z+ i+ I* X0 k) Z
- }
复制代码- // This Message overwrites its unique id with 0x7362d09c+ [, Z0 `- j9 r& \/ [+ o9 z
- message(0x7362d09c) TokenNotification {7 e# Z" v6 |! J$ A6 B% \4 b! f) m& L
- forwardPayload: Slice as remaining;
* C9 M8 `7 }# ? - }
复制代码 这对于要处理特定智能合约的某些操作码(如 Jetton standard)的情况非常有用。 该合约能够处理的操作码简表为此处以 FunC 表示。 它们是智能合约的接口。% E( O' U0 B; }5 U0 a
4 ]' {. N* e0 M1 F
% V- N: k2 s+ t- I4 ?操作- R% K! W2 r/ t7 M# H2 f" f" @6 b
实例化, Q" A( g: h) @4 \/ o
创建 Struct 和 Message 实例类似于 function calls,但需要用大括号 {}(大括号)代替小括号 ()指定参数:
% K; U+ h8 z( k1 g3 f, q- struct StA {
: Z5 k; E: J) p" ?; b; f) \ - field1: Int;# F; m) K: `' a% g5 N
- field2: Int;
3 Y; s2 m0 T% r, T/ P4 d - }" n4 T7 ^3 V* q- J+ q
) ~" I6 u$ y- W+ \! g: P- message MsgB {$ I8 f, d* N H4 ]
- field1: String;
# O+ ]" ?7 u1 f) L - field2: String;
$ s' J7 a: D* N" c6 x6 q - }
8 V S0 h8 \- W, p3 i U+ k b* u! \ - / w1 Z4 }3 I `( X, d9 e
- fun example() {
0 Z% \9 G7 e5 | - // Instance of a Struct StA
3 O# w9 T: H i- B - StA{
( m/ Y2 k; v1 Q" D% _6 B1 k! `% K - field1: 42,4 @) b/ {! z0 B7 }3 N8 o9 [0 {
- field2: 68 + 1, // trailing comma is allowed
2 `- `. S! g+ {8 t p: [ - };: o1 C$ R; t6 O3 N
- & H3 F5 L$ H5 K' d+ g% N8 t
- // Instance of a Message MsgB
# i5 {2 o: W; ?* a- {. }/ n% } - MsgB{
8 l* f/ y7 E9 A* H5 O - field1: "May the 4th"," f- Z j/ t2 M4 s, r. B# w
- field2: "be with you!", // trailing comma is allowed, l: u* e' T* g+ D% r2 i8 A8 R, s
- };
: g# a7 z+ w% \2 ^9 X - }
复制代码- struct PopQuiz {9 n$ W1 O* t, B8 y3 @, D/ X
- vogonsCount: Int;9 v2 ?* {) R0 `7 ]$ i4 Z' J) H
- nicestNumber: Int; P/ R) Y; n( A5 w9 X% ?
- }
% l/ A1 m# Y9 W - $ u( ]- H+ d9 E; m+ `3 m* B5 H6 z
- fun example() { z; }& b+ E e6 \$ u$ }, G
- // Let's introduce a couple of variables
: H5 E" D+ h0 }) q - let vogonsCount: Int = 42;6 V/ s/ n! b- C9 Z2 f+ B
- let nicestNumber: Int = 68 + 1;
. f. _+ V2 p/ i2 @
' D6 A8 G7 w3 \' Q8 S6 e. [- // You may instantiate the Struct as usual and assign variables to fields,
8 ~4 s9 S" `% U+ f - // but that is a bit repetitive and tedious at times9 [8 a" i8 Y4 f, l7 y5 M
- PopQuiz{ vogonsCount: vogonsCount, nicestNumber: nicestNumber };
$ U, b. i4 _: U5 w; l
5 [8 h- s: n0 l6 S) ^& K& Q- // Let's use field punning and type less,. t6 A) u) Y4 s* R; j# I
- // because our variable names happen to be the same as field names+ i9 N) {' F* c" K% j" B. M7 ?
- PopQuiz{
h' h7 V, @) ? - vogonsCount,
8 T' @, U6 v' O - nicestNumber, // trailing comma is allowed here too!/ ]+ ?) J3 K; A1 j* k$ s$ H$ [ [6 ?
- };
( p1 u. s+ s/ a* G - }
复制代码- struct Big {
6 o1 i9 m8 P) r5 e( j - f1: Int;
1 y# M' Q( r- a+ B7 [4 K5 M7 H - f2: Int;4 T c6 M2 n. a2 v* V
- f3: Int;
5 y$ j/ S0 V1 u6 H- f: V% P - f4: Int;
9 m5 r3 i. Y3 h" h L8 q3 w o% r - f5: Int;
+ P7 e/ f; X: C& x( X% t - f6: Int;; W) S( j% P8 i7 F {4 \
- }
1 N" z# |5 }/ r$ r( w: M9 j9 u+ |: _ - % g6 S- f: U9 e/ r9 W: ^
- fun conversionFun() {- J9 k) f2 r' K+ Y) e0 M
- dump(Big{
7 }9 O7 U! i" \% v4 S Z - f1: 10000000000, f2: 10000000000, f3: 10000000000,0 |# E3 P* `- l
- f4: 10000000000, f5: 10000000000, f6: 10000000000, W! c4 J5 J# F# P; w% \7 D
- }.toCell()); // x{...cell with references...}
- d% N9 I$ f$ `0 z - }
复制代码- struct Fizz { foo: Int }
8 Q) S$ ~; ~* w4 l( h- g - message(100) Buzz { bar: Int } ?0 W' {, g& {" I; g+ I+ o7 G
- 7 V: H% |( C# E. {% t, d; B% z
- fun constructThenParse() {+ H1 {) ], J2 m$ D& }
- let fizzCell = Fizz{foo: 42}.toCell();
( y& V/ Y# Q9 O+ ] - let buzzCell = Buzz{bar: 27}.toCell();
5 [7 K2 N* v, v! V" a
/ r6 n* |' V7 E/ I- let parsedFizz: Fizz = Fizz.fromCell(fizzCell);. E$ [, w9 O- O1 F1 C4 y
- let parsedBuzz: Buzz = Buzz.fromCell(buzzCell);. h( g( G1 D1 c4 X
- }
复制代码- struct ArbitraryStruct {} G3 ]6 f9 t. `" S$ E
- message(0x2A) ArbitraryMessage {}: w' i( G% [' [/ Y
) B, [! p2 l, x x) E0 m( ~- fun lawOne() {; @2 k6 k3 Z' X4 C% r' N% j
- let structInst = ArbitraryStruct{};) P: E# x) Q7 I' k/ c ]: g
- let messageInst = ArbitraryMessage{};& v: K9 P( L" w! o/ r
, D0 l: g. X; W- ArbitraryStruct.fromCell(structInst.toCell()); // = structInst
2 y- U- P3 S2 M# Z' i0 S - ArbitraryMessage.fromCell(messageInst.toCell()); // = messageInst
! R+ _6 e6 x. ^' [ - 6 M! L$ o; V+ _# w
- // Same goes for Slices, with .toCell().asSlice() and .fromSlice()
* [" x+ \1 P$ l, ]: \# p# E) p
1 p6 B8 C5 u$ R- ArbitraryStruct.fromSlice(structInst.toCell().asSlice()); // = structInst; q' I: q3 j& u
- ArbitraryMessage.fromSlice(messageInst.toCell().asSlice()); // = messageInst I: u. ]/ s1 Y
- }
复制代码 对于任何与给定 Struct/Message 具有相同 TL-B 布局的 cell,调用 Struct.fromCell()(或 Message.fromCell()),然后通过 .toCell() 将结果转换为 Cell,就会得到原始 cell 的副本:- struct ArbitraryStruct { val: Int as uint32 }* N; u- l( _- D X2 A. J
- message(0x2A) ArbitraryMessage {}
# i) o, C( |- x* s - * X* C2 C p4 {8 P
- fun lawTwo() {1 p; K4 D+ i3 D% l1 a+ ~
- // Using 32 bits to store 42 just so this cellInst can be
# {- o7 A; [! x8 k* o. T4 p - // re-used for working with both ArbitraryStruct and ArbitraryMessage
: r7 [6 l/ N* l1 s+ d% k7 }7 s8 C - let cellInst = beginCell().storeUint(42, 32).endCell();
. ], R4 `9 _/ |1 d
8 {; _; N& w+ g7 L- ArbitraryStruct.fromCell(cellInst).toCell(); // = cellInst
& Y! Q0 c6 f, Z" h - ArbitraryMessage.fromCell(cellInst).toCell(); // = cellInst0 r1 _5 x6 ` a6 S
! l- V. Z4 A, y0 ]# d' ]9 O- // Same goes for Slices, with .fromSlice() and .toCell().asSlice()
4 Y4 `6 b; | ^) u6 u% K0 W; m6 B9 v - let sliceInst = cellInst.asSlice();
1 E0 X8 J% u6 p7 j
0 x4 F: T/ W, r. @- ArbitraryStruct.fromSlice(sliceInst).toCell().asSlice(); // = sliceInst9 r# N# o* o' v2 `
- ArbitraryMessage.fromSlice(sliceInst).toCell().asSlice(); // = sliceInst0 h9 Q1 r& E1 h* }2 ]- q
- }
复制代码 ) K" v I9 o E: _* P- h2 Z" {5 z
|
|