SimTalk 变量与数据类型
一、变量概述
SimTalk 中的变量分为三种:局部变量 、全局变量 和参数。它们各自有不同的作用域和用途。
| 类型 | 说明 | 关键字 |
|---|---|---|
| 局部变量 | 仅在声明它的 Method 中可见 | var |
| 全局变量 | 以 Variable 对象存在,可被任何对象访问 | Variable 对象 |
| 参数 | 用于向 Method 传递值 | param |
- 局部变量:声明在 Method 内部,生命周期与 Method 执行周期一致,外部无法访问。
- 全局变量:通过 Variable 对象创建,存放在 Frame 或 Class Library 中,任何 Method 都可以通过路径访问。
- 参数:是 Method 接口的一部分,允许调用者向 Method 传递数据。
二、局部变量
声明语法
使用 var 关键字声明局部变量,可以同时声明多个同类型变量:
simtalk
var x, y: integer
声明时赋值
变量可以在声明的同时赋初始值。如果赋值了初始值,数据类型声明可以省略(编译器会根据初始值推断类型):
simtalk
var a: length := Track1.Length
默认初始值
如果声明变量时没有赋初始值,各数据类型的默认值如下:
| 数据类型 | 默认值 |
|---|---|
| 数值类型(Integer, Real 等) | 0 |
| Boolean | false |
| String | "" |
| Object | void |
| Time | 0:00:00 |
| Date | 1900/01/01 |
循环中声明的变量行为
- 如果变量声明时没有初始赋值,它不会在每次循环迭代时重新初始化,而是保留上一次循环结束时的值。
- 如果变量声明时有初始赋值,则每次循环都会重新赋值。
simtalk
-- 循环中声明变量的行为
for var i := 1 to 3
var x: integer -- 不重新初始化,保留上次值
var y: integer := 0 -- 每次循环重新赋值
print x, " ", y
x += 1
y += 1
next
-- 输出: 0 0 --> 1 0 --> 2 0
if 语句中声明的变量
在 if 语句中声明的变量,在 if 语句外部仍然可见:
simtalk
if condition then
var temp: integer := 42
end
print temp -- 在 if 外部仍可访问
完整代码示例
simtalk
var a := Track1.length
var b := Track2.length
var c := sqrt(a*a + b*b)
print c
三、数据类型概述
SimTalk 提供了丰富的数据类型,涵盖基础类型、带单位类型、集合类型和特殊类型。
基础类型
| 类型 | 说明 |
|---|---|
integer |
整数类型 |
real |
实数类型(浮点数) |
boolean |
布尔类型(true/false) |
string |
字符串类型 |
object |
对象引用类型 |
any |
任意类型(可接受任何类型的值) |
带单位类型
| 类型 | 说明 | 单位 |
|---|---|---|
length |
长度 | m(米) |
speed |
速度 | m/s |
acceleration |
加速度 | m/s² |
weight |
重量 | kg |
time |
时间 | s |
date |
日期 | - |
datetime |
日期时间 | - |
集合类型
| 类型 | 说明 |
|---|---|
array |
数组(固定大小,通过索引访问) |
list |
列表(通过索引访问) |
stack |
栈(后进先出) |
queue |
队列(先进先出) |
table |
表格(行列结构) |
特殊类型
| 类型 | 说明 |
|---|---|
json |
JSON 数据类型 |
method |
方法引用类型 |
money |
货币类型(仅限全局变量和自定义属性) |
注意 :
Money和RandTime不是 SimTalk 数据类型。Money 仅用于全局变量和自定义属性;本地变量应使用real代替。RandTime 用于生成独立的随机时间数。
四、常量值
Boolean 常量
simtalk
var flag: boolean := true
var done: boolean := false
Integer 常量
整数范围:-9223372036854775807 到 9223372036854775807
simtalk
var count: integer := 100
var largeNum: integer := 9223372036854775807
Real 常量
支持小数点和科学记数法,指数范围 -307, 307:
simtalk
var pi_approx: real := 3.14159
var sci: real := 1.0e2 -- 等价于 100.0
var very_small: real := 1.5e-10
String 常量
- 用双引号包裹
- 最大长度为 1024 个字符
- 使用反斜杠
\来保护引号和换行
simtalk
-- 字符串常量
priority := "Urgent"
print "It is \"very\" urgent."
simtalk
-- 多行字符串
address := "Frank Jones\
Halford Lane 9\
Cedar Rapids, IA 52409"
simtalk
-- 字符串拼接
s := "This is a long string," +
" formed by linking together several sub-strings."
pi 常量
pi 是 SimTalk 内置的圆周率常量,数据类型为 real:
simtalk
var circumference: real := 2 * pi * radius
五、Any 数据类型
any 是一种特殊的类型,它可以接受任何类型的值。
特性
- 首次赋值确定数据类型 :当第一次为
any变量赋值时,该变量的类型就确定了。 - 使用
forget重置类型 :调用forget后,变量恢复为未初始化状态,可以重新赋值为不同类型。
类型检查函数
SimTalk 提供了一系列类型检查函数,用于判断 any 变量当前的实际类型:
| 函数 | 检查类型 |
|---|---|
isString(x) |
字符串 |
isInteger(x) |
整数 |
isReal(x) |
实数 |
isLength(x) |
长度 |
isSpeed(x) |
速度 |
isAcceleration(x) |
加速度 |
isTime(x) |
时间 |
isDate(x) |
日期 |
isDatetime(x) |
日期时间 |
isWeight(x) |
重量 |
isBoolean(x) |
布尔 |
isObject(x) |
对象引用 |
isList(x) |
列表 |
isQueue(x) |
队列 |
isStack(x) |
栈 |
isTable(x) |
表格 |
isJson(x) |
JSON |
isArray(x) |
数组 |
还可以使用 getSimTalkTypename 函数获取变量的类型名称字符串。
代码示例
simtalk
param arg: any
if isLength(arg)
print "length = ", arg
end
simtalk
-- switch 示例
switch getSimTalkTypename(a)
case "integer"
print "integer argument"
case "string"
print "string argument"
end
六、Acceleration 数据类型
加速度(Acceleration)是一种带单位的实数类型。
| 属性 | 值 |
|---|---|
| 范围 | -8.9e307 ≤ acceleration ≤ 8.9e307 |
| 基本单位 | m/s² |
| 支持单位后缀 | mps², fps² |
simtalk
var a: acceleration := 9.81mps²
var b: acceleration := 32.2fps²
七、参数声明
使用 param 关键字声明 Method 的参数。
基本语法
simtalk
param minimum, maximum: real
可以声明多个不同类型的参数:
simtalk
param rpm: real, tool: string
引用传递(byref)
使用 byref 关键字实现引用传递,允许 Method 修改调用者传入的变量:
simtalk
param byref x: integer, byref y: real
x := x + 1
y := y * 2
集合类型参数
simtalk
param order: list, orders, deliveries: queue
八、默认参数
语法
参数可以在声明时指定默认值:
simtalk
param x: integer := 123
规则
- 默认值传播:有默认值的参数之后的所有参数都必须有默认值。
- 允许的默认值类型:
| 数据类型 | 允许的默认值 |
|---|---|
| 数字类型 | 数字常量 |
| string | 字符串常量 |
| boolean | true / false |
| object | void |
| any | void |
| date / datetime | 不能有默认值 |
| array | [] 或 {} |
| byref 参数 | 不能有默认值 |
注意 :
object、table、list、stack、queue、any只能以void为默认值。
代码示例
simtalk
param a: string,
b, c: string := "",
d: boolean := true
-- 可调用: Method("A")
-- 可调用: Method("A", "B", "C", false)
九、函数返回值
声明返回类型
使用 -> 声明 Method 的返回类型:
simtalk
-> real
也可以在 param 行中同时声明参数和返回值:
simtalk
param CustomerNo: integer -> string
param orders, deliveries: list, delivery_date: time -> table
赋值返回值
在函数体内,使用 result 关键字赋值返回值:
simtalk
result := "Hello"
提前退出
使用 return 语句可以提前退出函数:
simtalk
if input < 0 then
result := -1
return
end
result := sqrt(input)
完整示例:返回含增值税的价格列表
simtalk
param pricelist: queue, VAT: real -> list[real]
var i: integer
result.create
i := 1
while not pricelist.empty loop
result[i] := pricelist.pop * (1 + VAT)
i := i + 1
end
十、Money 和 RandTime(非 SimTalk 数据类型)
Money
Money不是 SimTalk 数据类型,不能用于局部变量声明。- Money 仅用于全局变量 (Variable 对象)和自定义属性。
- 如果需要在局部变量中表示货币值,请使用
real类型代替。
RandTime
RandTime用于生成独立的随机时间数,它不是 SimTalk 数据类型。- 主要用于仿真中的随机时间生成场景。