惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

The GitHub Blog
The GitHub Blog
Jina AI
Jina AI
月光博客
月光博客
博客园 - Franky
小众软件
小众软件
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
V
Visual Studio Blog
有赞技术团队
有赞技术团队
V
V2EX
IT之家
IT之家
阮一峰的网络日志
阮一峰的网络日志
Stack Overflow Blog
Stack Overflow Blog
H
Help Net Security
Apple Machine Learning Research
Apple Machine Learning Research
腾讯CDC
D
DataBreaches.Net
Hugging Face - Blog
Hugging Face - Blog
Martin Fowler
Martin Fowler
罗磊的独立博客
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
WordPress大学
WordPress大学
C
Check Point Blog
Microsoft Azure Blog
Microsoft Azure Blog
Microsoft Security Blog
Microsoft Security Blog

博客园 - 方东信

【far 语言】语言文档目录 【far 语言】注解系统 【far 语言】数组 【far 语言】并发编程(协程) 【far 语言】控制流 【far 语言】异常处理 【far 语言】farcc 构建工具 【far 语言】函数 【far 语言】组合与继承 【far 语言】接口与泛型 【far 语言】List 列表 【far 语言】Map 映射 【far 语言】原生内存与 FFI 【far 语言】字符串 【far 语言】类型系统 Java 远程调用类,控制类的办法,老了,记不住了。靠 java opc ua 基于s7 音视频:JavaCV 采集桌面画面并显示的方法 pand3d实现服务端渲染并推流 UI弹窗遮罩屏蔽触发事件的处理 far的数据类型 Windows下Tesseract-OCR的安装与使用 LoRA配置 大模型三阶段训练方法(LLaMa Factory) windows系统下anaconda的安装和使用 trl ppo 【手把手从零实现】Qwen2.5-VL:环境配置/功能实验(图片识别理解、目标检测、文字OCR、文档解析、视频理解)/模型微调(MS-Swift 和 LLaMA-Factory) seata 1.8.0 报错大全 Springboot 报错 java.lang.IllegalStateException: block()/blockFirst()/blockLast() are blocking vLLM部署多模态大模型Qwen2.5-VL-3B-Instruct
【far 语言】语法总览
方东信 · 2026-09-13 · via 博客园 - 方东信

本文是「far 语言」系列文档之一,总目录见《【far 语言】语言文档目录》。

Far 语法速览

Far 语法融合了 JS 的灵动、Java 的严谨与 C 的直白。本文面向初识 far 的开发者,用最短篇幅带你读懂它。

你好,far

class App {
    static long main(string args[]){
        println("你好,far!");
        return 0;
    }
}

每个 .far 文件就是一个类,文件名即类名。入口固定为 static long main(string args[]),方法默认返回 0,可不写 return

变量与类型

string name = "far";                    // 字符串
long age = 30;                          // 64 位整数(默认数值类型)
int score = 100;                        // 32 位整数注解
double pi = 3.14;                       // 双精度浮点
bool ok = true;                         // 布尔
byte b = 0x48;                          // 8 位整数注解
x := 1;                              // 短变量声明 :=(自动推断类型,Go 风格)
map<string, string> data = {"name": "far"};  // 字典
object obj = new App();                // 对象 / 自定义类实例
  • 类型写在变量名前;短变量声明 x := 表达式 自动推断。
  • int/short/byte 是编译期宽度注解,运行时统一 64 位。
  • map 键可以是 stringlong,字面量用 {...}key 可以省略引号{name: "far", if: 123}

数组

数组采用 C 风格声明,方括号挂在变量名后,字面量用花括号:

int data[3] = [1,2,3];              // 定长数组(数量必须严格相等)
string names[] = ["a","b","c"];     // 未定长(动态)
int m[2][3] = [[1,2,3],[4,5,6]];    // 多维数组
object x[] = [1, 2.1, "3"];         // 混合类型(元素统一 far 对象)
bb := ["4","5"];                 // := 推导(元素类型一致)

names.push("d");        // 追加
names.pop();            // 弹出末尾
names[0] = "x";         // 下标读写
println(sizeof(names)); // 长度

方法

class App {
    // 静态方法,默认返回 0,可不写 return
    static long sum(long a, long b){
        return a + b;
    }

    // 参数默认值(带默认值的参数必须放在最后)
    static long greet(string name, long times = 1){
        for(long i = 0; i < times; i++){
            println("你好," + name);
        }
        return 0;
    }

    // 数组参数与返回
    static long first(int x[3]){ return x[0]; }
    static int[] getList(){ return [1,2,3]; }

    static long main(string args[]){
        long r = this::sum(3, 4);    // 静态方法用 :: 调用
        println(r);
        this::greet("far");          // 缺省参数
        this::greet("far", 3);
        return 0;
    }
}
  • 匿名函数:f := (x,y)-> println(x + y);,可捕获外部变量。
  • 参数解构(传 map 或数组均可),适合"具名可选参数"场景:
static long test(string type, {string name, long age}){
    println(fmt("%s %s %s", type, name, age));
}

// 调用:传 map 或数组都行
this::test("大学生", {"name":"张三", "age":21});
this::test("大学生", {"张三", 21});
  • 真·变长参数用 T... name(只能放最后),见下节与 function.md

类、接口与继承

一个 .far 文件内可声明多个类与接口;main 所在类为入口。

interface Named {
    string name();
}

class Animal {
    long hp = 100;
    string speak(){ return "animal"; }
}

// 单继承用冒号;多接口用 impl 逗号列表
class Dog : Animal impl Named {
    @Override
    string speak(){ return super.speak() + "+woof"; }
    string name(){ return "dog"; }
}

class App {
    static long main(string args[]){
        Named n = new Dog();        // 接口变量 ⇒ 动态分派
        println(n.name());          // dog
        Animal a = new Dog();       // 向上转型
        println(a.speak());         // animal+woof(按运行期类型分派)
        return 0;
    }
}
  • 只允许单继承(多继承会报错);需要多个能力请写 impl I1, I2
  • super.method() 调父类实现;@Override 断言真覆盖,签名写错立刻报错。
  • 父类字段初始化器自动执行;子类字段不得与父类同名(编译报错)。
  • 接口之间可继承(接口无状态,可多个):interface IChild : IParentA, IParentB { }
  • 详见 inherit.mdinterface-generic.md

流程控制

// if / else
if (a == 1) {
    b = 2;
} else if (a == 2) {
    b = 3;
} else {
    b = 4;
}

// for(初始器 / 条件 / 执行器 都可省略)
for(long i = 0; i < 10; i++){
    println(i);
}

// foreach 遍历 map / 数组
foreach(k in data){ println(data[k]); }   // k 是 key
foreach(v in arr){ println(v); }          // v 是元素
foreach(idx, v in arr){ println(idx); }   // idx 是索引

// when 表达式(比 switch 更强,带返回值)
r := when{
    a == 2 => "等于2";
    a in (1,2,3) => "在集合里";
    a in 1..20 => "在区间里";
    _ => "默认";
};

// 区间表达式
if (x in 1..10){ println("x 在 1..10"); }

并发:虚拟线程 + Channel

Far 的所有异步任务统一为虚拟线程(vtNew),通信只走 Channel,select 多路等待。

class App {
    static long main(string args[]){
        // 创建通道对(tx 发送端 / rx 接收端)
        map<string, object> ch = chanPair();
        map<string, object> tx = ch.tx;
        map<string, object> rx = ch.rx;

        // 创建并启动虚拟线程(匿名方法闭包,端点由闭包捕获)
        map<string, object> t = vtNew((dummy)->{
            string msg = chanRecv(rx);
            chanSend(tx, "got: " + msg);
        }, 0, 0, "worker");
        vtStart(t);

        // 主协程发送并阻塞接收
        chanSend(tx, "hello");
        string r = chanRecv(rx);
        println(r);
        return 0;
    }
}

select 多路等待多个 Channel:

select {
    case msg = cmd_rx.recv() => {
        if (msg == "quit") { break; }
    }
    case data = data_rx.recv() => { ... }
    timeout(100) => { }         // 超时分支
}

字符串

s := "Hello Far World";
println(s.len());                       // 15
println("  AbC  ".trim().toLowerCase()); // abc
println("a,b,c".split(",")[1]);         // b
println(s.charAt(1));                   // e

// 字符串模板
name := "far";
println(`Hello ${name}!`);              // Hello far!

集合:List

import List;                            // 导入标准库

List<long> nums = new List();
nums.add(1);
nums.add(2);
println(nums.size());                   // 2
println(nums.get(1));                   // 2
println(nums.toString());               // [1,2]

注解(Java 风格)

@Extern("c", "strlen")                  // 内建:FFI 声明外部 C 函数
static long strlen(RawPtr<AbiChar> s);

@Retention(RUNTIME)
@Target(CLASS, METHOD)
annotation MyAnno {
    string name;
}
  • 注解名首字母必须大写。
  • 默认只保留到编译期(SOURCE);@Retention(RUNTIME) 可让注解在运行期被反射读取。

原生内存:bytes + load/store

buf := bytes(64);                    // 分配 64 字节连续内存
bytesStore<i32>(buf, 0, 42);                 // 类型化写入
x := bytesLoad<i32>(buf, 0);              // 类型化读取
println(x);                             // 42

异常处理

try {
    throw "出错啦";
} catch (Exception e) {
    println(e.getMessage());
} finally {
    println("无论是否异常都会执行");
}

完整语法参考:grammar/all.md(由编译器源码核对);并发架构见 concurrency-final.md

Rust编程语言群 1036955113
java新手自学群 626070845
java/springboot/hadoop/JVM 群 4915800
Hadoop/mongodb(搭建/开发/运维)Q群481975850
GOLang Q1群:6848027
GOLang Q2群:450509103
GOLang Q3群:436173132
GOLang Q4群:141984758
GOLang Q5群:215535604
C/C++/QT群 1414577
单片机嵌入式/电子电路入门群群 306312845
MUD/LIB/交流群 391486684
Electron/koa/Nodejs/express 214737701
大前端群vue/js/ts 165150391
操作系统研发群:15375777
汇编/辅助/破解新手群:755783453
大数据 elasticsearch 群 481975850
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。