DolphinDB自定义函数:打造专属工具库

目录

    • 摘要
    • 一、函数基础
      • [1.1 函数定义语法](#1.1 函数定义语法)
      • [1.2 函数组成部分](#1.2 函数组成部分)
      • [1.3 返回值](#1.3 返回值)
    • 二、参数传递
      • [2.1 位置参数](#2.1 位置参数)
      • [2.2 默认参数](#2.2 默认参数)
      • [2.3 可变参数](#2.3 可变参数)
      • [2.4 参数类型检查](#2.4 参数类型检查)
    • 三、高级特性
      • [3.1 闭包](#3.1 闭包)
      • [3.2 高阶函数](#3.2 高阶函数)
      • [3.3 递归函数](#3.3 递归函数)
      • [3.4 函数重载](#3.4 函数重载)
    • 四、匿名函数与Lambda
      • [4.1 匿名函数](#4.1 匿名函数)
      • [4.2 部分应用](#4.2 部分应用)
      • [4.3 函数组合](#4.3 函数组合)
    • 五、工业物联网实战案例
      • [5.1 设备状态判断函数](#5.1 设备状态判断函数)
      • [5.2 设备健康评分函数](#5.2 设备健康评分函数)
      • [5.3 异常检测函数](#5.3 异常检测函数)
      • [5.4 数据质量检查函数](#5.4 数据质量检查函数)
    • 六、模块化编程
      • [6.1 模块定义](#6.1 模块定义)
      • [6.2 模块使用](#6.2 模块使用)
      • [6.3 函数库管理](#6.3 函数库管理)
    • 七、性能优化
      • [7.1 向量化优化](#7.1 向量化优化)
      • [7.2 避免重复计算](#7.2 避免重复计算)
      • [7.3 使用内置函数](#7.3 使用内置函数)
    • 八、调试技巧
      • [8.1 打印调试](#8.1 打印调试)
      • [8.2 断言检查](#8.2 断言检查)
      • [8.3 异常处理](#8.3 异常处理)
    • 九、最佳实践
      • [9.1 函数设计原则](#9.1 函数设计原则)
      • [9.2 代码示例](#9.2 代码示例)
    • 十、总结
    • 参考资料

摘要

本文深入讲解DolphinDB自定义函数的开发技巧,从基础函数定义到高级特性应用。详细介绍参数传递、返回值处理、闭包、递归、函数重载等核心概念,并提供工业物联网场景的实战案例。同时涵盖模块化编程、函数库管理、性能优化等最佳实践,帮助读者构建高效可复用的函数库。本文适合需要在DolphinDB上进行应用开发的工程师阅读。


一、函数基础

1.1 函数定义语法

DolphinDB使用 def 关键字定义函数:

python 复制代码
// 基本函数定义
def add(a, b) {
    return a + b
}

// 调用函数
add(1, 2)                     // 3
add(1.5, 2.5)                 // 4.0

1.2 函数组成部分

函数结构
def关键字
函数名
参数列表
函数体
返回值

1.3 返回值

python 复制代码
// 单返回值
def square(x) {
    return x * x
}
square(5)                     // 25

// 多返回值
def stats(v) {
    return avg(v), max(v), min(v), std(v)
}
a, m, n, s = stats(1..100)
// a=50.5, m=100, n=1, s=28.866

// 无返回值
def printInfo(msg) {
    print("INFO: " + msg)
}
printInfo("Hello")            // 打印信息,返回void

二、参数传递

2.1 位置参数

python 复制代码
// 位置参数(按顺序传递)
def createPoint(x, y, z) {
    return [x, y, z]
}
createPoint(1, 2, 3)          // [1, 2, 3]

2.2 默认参数

python 复制代码
// 默认参数
def greet(name, greeting="Hello") {
    return greeting + ", " + name + "!"
}

greet("DolphinDB")            // "Hello, DolphinDB!"
greet("DolphinDB", "Hi")      // "Hi, DolphinDB!"
greet("DolphinDB", greeting="Welcome")  // "Welcome, DolphinDB!"

2.3 可变参数

python 复制代码
// 可变参数
def sumAll(...) {
    args = getArgs()
    total = 0
    for (arg in args) {
        total += arg
    }
    return total
}

sumAll(1, 2, 3, 4, 5)         // 15
sumAll(10, 20, 30)            // 60

2.4 参数类型检查

python 复制代码
// 类型检查函数
def safeDivide(a, b) {
    if (typestr(a) != "DOUBLE" and typestr(a) != "INT") {
        throw "参数a必须是数值类型"
    }
    if (typestr(b) != "DOUBLE" and typestr(b) != "INT") {
        throw "参数b必须是数值类型"
    }
    if (b == 0) {
        throw "除数不能为0"
    }
    return a / b
}

safeDivide(10, 2)             // 5
safeDivide(10, 0)             // 抛出异常

三、高级特性

3.1 闭包

闭包是指函数可以访问其外部作用域的变量:

python 复制代码
// 闭包示例
def makeMultiplier(factor) {
    // 返回一个函数,该函数可以访问外部的factor变量
    return def (x) {
        return x * factor
    }
}

double = makeMultiplier(2)
triple = makeMultiplier(3)

double(5)                     // 10
triple(5)                     // 15

3.2 高阶函数

高阶函数是指接受函数作为参数或返回函数的函数:

python 复制代码
// 高阶函数:接受函数作为参数
def applyTwice(f, x) {
    return f(f(x))
}

def addOne(x) { return x + 1 }
applyTwice(addOne, 5)          // 7

// 高阶函数:返回函数
def makeAdder(n) {
    return def (x) { return x + n }
}

add5 = makeAdder(5)
add5(10)                       // 15

3.3 递归函数

python 复制代码
// 递归计算阶乘
def factorial(n) {
    if (n <= 1) return 1
    return n * factorial(n - 1)
}
factorial(5)                   // 120

// 递归计算斐波那契数列
def fibonacci(n) {
    if (n <= 1) return n
    return fibonacci(n - 1) + fibonacci(n - 2)
}
fibonacci(10)                  // 55

// 尾递归优化版本
def factorialTail(n, acc=1) {
    if (n <= 1) return acc
    return factorialTail(n - 1, n * acc)
}
factorialTail(100)             // 100!

3.4 函数重载

DolphinDB不支持传统函数重载,但可以通过参数判断实现:

python 复制代码
// 通过参数类型实现"重载"
def process(data) {
    type = typestr(data)
    
    if (type == "INT" or type == "DOUBLE") {
        return data * 2
    } else if (type == "STRING") {
        return upper(data)
    } else if (type == "VECTOR") {
        return data * 2
    } else {
        throw "不支持的类型: " + type
    }
}

process(10)                    // 20
process("hello")               // "HELLO"
process([1, 2, 3])             // [2, 4, 6]

四、匿名函数与Lambda

4.1 匿名函数

python 复制代码
// 匿名函数定义
f = def (x) { return x * x }
f(5)                           // 25

// 简写形式(Lambda表达式)
f = def (x) { x * x }          // 省略return
f(5)                           // 25

// 在高阶函数中使用
each(def (x) { x * 2 }, 1..5)  // [2, 4, 6, 8, 10]

4.2 部分应用

python 复制代码
// 部分应用:固定部分参数
def add(a, b, c) {
    return a + b + c
}

// 固定第一个参数
add5 = add{5, }
add5(1, 2)                     // 8

// 固定后两个参数
add10 = add{, 5, 5}
add10(1)                       // 11

// 固定中间参数
addMiddle = add{, 5, }
addMiddle(1, 2)                // 8

4.3 函数组合

python 复制代码
// 函数组合
def compose(f, g) {
    return def (x) { return f(g(x)) }
}

double = def (x) { x * 2 }
increment = def (x) { x + 1 }

doubleThenIncrement = compose(increment, double)
doubleThenIncrement(5)         // 11

incrementThenDouble = compose(double, increment)
incrementThenDouble(5)         // 12

五、工业物联网实战案例

5.1 设备状态判断函数

python 复制代码
// 设备状态综合判断
def getDeviceStatus(temperature, humidity, pressure, vibration) {
    // 温度状态
    tempStatus = iif(temperature > 35, "高温警告",
                 iif(temperature < 10, "低温警告", "正常"))
    
    // 湿度状态
    humidStatus = iif(humidity > 80, "高湿警告",
                  iif(humidity < 30, "低湿警告", "正常"))
    
    // 压力状态
    pressStatus = iif(pressure > 1020, "高压警告",
                  iif(pressure < 980, "低压警告", "正常"))
    
    // 振动状态
    vibStatus = iif(vibration > 4.0, "振动异常",
                iif(vibration > 3.0, "振动偏高", "正常"))
    
    // 综合判断
    warnings = [tempStatus, humidStatus, pressStatus, vibStatus]
    warningCount = sum(iif(warnings != "正常", 1, 0))
    
    if (warningCount == 0) {
        return "正常"
    } else if (warningCount == 1) {
        return "轻微异常"
    } else if (warningCount <= 2) {
        return "中度异常"
    } else {
        return "严重异常"
    }
}

// 应用函数
getDeviceStatus(38.0, 50.0, 1010.0, 2.0)   // "轻微异常"(高温)
getDeviceStatus(38.0, 85.0, 1025.0, 4.5)   // "严重异常"

5.2 设备健康评分函数

python 复制代码
// 设备健康评分计算
def calculateHealthScore(temperature, humidity, pressure, vibration, power) {
    // 温度评分(理想值25°C)
    tempScore = 100 - abs(temperature - 25) * 2
    tempScore = max(0, min(100, tempScore))
    
    // 湿度评分(理想值50%)
    humidScore = 100 - abs(humidity - 50) * 0.5
    humidScore = max(0, min(100, humidScore))
    
    // 压力评分(理想值1013hPa)
    pressScore = 100 - abs(pressure - 1013) * 0.1
    pressScore = max(0, min(100, pressScore))
    
    // 振动评分(越小越好)
    vibScore = 100 - vibration * 20
    vibScore = max(0, min(100, vibScore))
    
    // 功率评分(稳定性)
    // 这里假设power是当前功率,理想值300W
    powerScore = 100 - abs(power - 300) * 0.1
    powerScore = max(0, min(100, powerScore))
    
    // 综合评分(加权平均)
    weights = [0.25, 0.20, 0.15, 0.25, 0.15]
    scores = [tempScore, humidScore, pressScore, vibScore, powerScore]
    
    totalScore = 0
    for (i in 0..5) {
        totalScore += scores[i] * weights[i]
    }
    
    return totalScore
}

// 批量应用
t = table(
    rand(20..30, 100) as temperature,
    rand(40..60, 100) as humidity,
    rand(1000..1020, 100) as pressure,
    rand(0.0..5.0, 100) as vibration,
    rand(100..500, 100) as power
)

t[`healthScore] = each(calculateHealthScore, 
    t.temperature, t.humidity, t.pressure, t.vibration, t.power)

5.3 异常检测函数

python 复制代码
// 基于Z-score的异常检测
def detectAnomaly(data, threshold=3.0) {
    mean = avg(data)
    stdDev = std(data)
    
    if (stdDev == 0) {
        return false
    }
    
    zScore = abs((data - mean) / stdDev)
    return zScore > threshold
}

// 批量异常检测
def detectAnomalies(data, window=10, threshold=3.0) {
    n = size(data)
    result = array(BOOL, n, n, false)
    
    for (i in window..n) {
        windowData = data[(i-window+1):(i+1)]
        result[i] = detectAnomaly(data[i], threshold) and 
                    detectAnomaly(windowData, threshold)
    }
    
    return result
}

// 应用示例
data = rand(100.0, 1000)
data[500] = 500  // 注入异常值
anomalies = detectAnomalies(data)
sum(anomalies)  // 异常点数量

5.4 数据质量检查函数

python 复制代码
// 数据质量检查
def checkDataQuality(table, columns) {
    results = table(1:0, `column`total`null_count`null_rate`unique_count`min_val`max_val, 
                    [STRING, LONG, LONG, DOUBLE, LONG, STRING, STRING])
    
    for (col in columns) {
        data = table[col]
        total = size(data)
        nullCount = sum(isNull(data))
        nullRate = nullCount * 100.0 / total
        uniqueCount = size(distinct(data))
        minVal = string(min(data))
        maxVal = string(max(data))
        
        results.append!(table(col, total, nullCount, nullRate, uniqueCount, minVal, maxVal))
    }
    
    return results
}

// 使用示例
t = loadTable("dfs://sensor_db", "sensor_data")
quality = checkDataQuality(t, `temperature`humidity`pressure)

六、模块化编程

6.1 模块定义

python 复制代码
// 文件: modules/iot_functions.dos

// 模块声明
module iot_functions

// ========== 状态判断函数 ==========

def getDeviceStatus(temperature, humidity, pressure, vibration) {
    tempStatus = iif(temperature > 35, "高温警告",
                 iif(temperature < 10, "低温警告", "正常"))
    humidStatus = iif(humidity > 80, "高湿警告",
                  iif(humidity < 30, "低湿警告", "正常"))
    pressStatus = iif(pressure > 1020, "高压警告",
                  iif(pressure < 980, "低压警告", "正常"))
    vibStatus = iif(vibration > 4.0, "振动异常",
                iif(vibration > 3.0, "振动偏高", "正常"))
    
    warnings = [tempStatus, humidStatus, pressStatus, vibStatus]
    warningCount = sum(iif(warnings != "正常", 1, 0))
    
    return iif(warningCount == 0, "正常",
           iif(warningCount == 1, "轻微异常",
           iif(warningCount <= 2, "中度异常", "严重异常")))
}

// ========== 健康评分函数 ==========

def calculateHealthScore(temperature, humidity, pressure, vibration, power) {
    tempScore = max(0, min(100, 100 - abs(temperature - 25) * 2))
    humidScore = max(0, min(100, 100 - abs(humidity - 50) * 0.5))
    pressScore = max(0, min(100, 100 - abs(pressure - 1013) * 0.1))
    vibScore = max(0, min(100, 100 - vibration * 20))
    powerScore = max(0, min(100, 100 - abs(power - 300) * 0.1))
    
    return tempScore * 0.25 + humidScore * 0.20 + pressScore * 0.15 + 
           vibScore * 0.25 + powerScore * 0.15
}

// ========== 单位转换函数 ==========

def celsiusToFahrenheit(celsius) {
    return celsius * 9 / 5 + 32
}

def fahrenheitToCelsius(fahrenheit) {
    return (fahrenheit - 32) * 5 / 9
}

def pascalToBar(pascal) {
    return pascal / 100000
}

def barToPascal(bar) {
    return bar * 100000
}

6.2 模块使用

python 复制代码
// 加载模块
use iot_functions

// 使用模块中的函数
status = getDeviceStatus(38.0, 50.0, 1010.0, 2.0)
score = calculateHealthScore(25.0, 50.0, 1013.0, 1.0, 300.0)
fahrenheit = celsiusToFahrenheit(25.0)

6.3 函数库管理

函数库结构
modules/
iot_functions.dos

物联网函数
statistical.dos

统计函数
utils.dos

工具函数
状态判断
健康评分
单位转换
描述统计
假设检验
字符串处理
日期处理


七、性能优化

7.1 向量化优化

python 复制代码
// 不推荐:循环调用
def processEach(data) {
    result = array(DOUBLE, 0)
    for (d in data) {
        result.append!(d * 2 + 1)
    }
    return result
}

// 推荐:向量化处理
def processVector(data) {
    return data * 2 + 1
}

// 性能对比
data = rand(100.0, 1000000)
// processEach(data)  // 慢
// processVector(data)  // 快100倍以上

7.2 避免重复计算

python 复制代码
// 不推荐:重复计算
def badExample(data) {
    return avg(data) + max(data) - avg(data)  // avg计算两次
}

// 推荐:缓存结果
def goodExample(data) {
    avgVal = avg(data)
    return avgVal + max(data) - avgVal
}

7.3 使用内置函数

python 复制代码
// 不推荐:自己实现
def mySum(data) {
    total = 0
    for (d in data) {
        total += d
    }
    return total
}

// 推荐:使用内置函数
sum(data)  // 内置函数经过高度优化

八、调试技巧

8.1 打印调试

python 复制代码
def debugExample(x, y) {
    print("输入参数: x=" + string(x) + ", y=" + string(y))
    
    result = x + y
    print("中间结果: " + string(result))
    
    result = result * 2
    print("最终结果: " + string(result))
    
    return result
}

8.2 断言检查

python 复制代码
def safeFunction(data) {
    assert(size(data) > 0, "数据不能为空")
    assert(typestr(data) == "VECTOR", "参数必须是向量")
    
    result = avg(data)
    assert(not isNull(result), "计算结果不能为空")
    
    return result
}

8.3 异常处理

python 复制代码
def robustFunction(data) {
    try {
        result = someRiskyOperation(data)
        return result
    } catch(ex) {
        print("错误: " + ex)
        return null
    }
}

九、最佳实践

9.1 函数设计原则

原则 说明 示例
单一职责 一个函数只做一件事 calculateAvg() 而非 calculateAll()
命名清晰 函数名表达意图 getDeviceStatus() 而非 check()
参数合理 参数数量适中 不超过5个参数
有文档 添加注释说明 说明参数、返回值

9.2 代码示例

python 复制代码
// 好的函数设计
/**
 * 计算设备健康评分
 * @param temperature 温度(摄氏度)
 * @param humidity 湿度(百分比)
 * @param pressure 压力(hPa)
 * @param vibration 振动(mm/s)
 * @param power 功率(W)
 * @return 健康评分(0-100)
 */
def calculateHealthScore(temperature, humidity, pressure, vibration, power) {
    // 实现代码...
}

十、总结

本文详细介绍了DolphinDB自定义函数的开发技巧。核心要点如下:

  1. 函数基础:定义、参数、返回值
  2. 高级特性:闭包、高阶函数、递归
  3. 匿名函数:Lambda表达式、部分应用
  4. 工业应用:状态判断、健康评分、异常检测
  5. 模块化:模块定义、函数库管理
  6. 性能优化:向量化、避免重复计算

思考题

  1. 如何设计一个可复用的设备状态判断函数库?
  2. 闭包在工业物联网场景中有哪些应用?
  3. 如何平衡函数的灵活性和性能?

参考资料

相关推荐
深念Y1 天前
AI 写代码总跑偏?我逼它回到“函数级颗粒度”
ai·软件工程·agent·函数·coding·vibe coding·代码补全
七夜zippoe2 天前
DolphinDB SQL查询:从简单到复杂
数据库·sql·mysql·查询·dolphindb
七夜zippoe3 天前
DolphinDB SQL查询:从基础到进阶
数据库·sql·进阶·聚合·dolphindb
C雨后彩虹3 天前
Java Lambda & Stream 避坑指南:20个高频错误案例分析与修复
java·stream·lambda·并行流
来自远方的老作者4 天前
第9章 函数-9.9 函数式编程
python·函数·回调函数·lambda表达式·函数闭包·偏函数·函数装饰器
七夜zippoe4 天前
DolphinDB脚本语言:从入门到精通
后端·struts·脚本·语言·dolphindb
TG_yunshuguoji4 天前
亚马逊云代理商:如何使用 CloudWatch 监控 AWS Lambda 函数日志?
云计算·aws·lambda·云服务器·cloudwatch
七夜zippoe5 天前
DolphinDB数据模型:表、分区与分布式表
分布式·wpf·数据模型··dolphindb
西西弗Sisyphus6 天前
Python Lambda 表达式等价普通函数实现
python·lambda