@FunctionalInterface public interface CheckAnswerFunction<T, U> { /** * 校验函数 * * @param t 正确答案 * @param u 用户答案 * @return 返回 boolean */ boolean checkAnswer(T t, U u); }
时间: 2024-01-17 19:14:46 浏览: 72
这是一个 Java 8 中的函数式接口定义,该接口只包含一个抽象方法 `checkAnswer`,可以用于定义校验答案的函数。这个函数接受两个参数,一个是正确答案 `t`,一个是用户答案 `u`,并返回一个布尔值表示用户答案是否正确。由于该接口只有一个抽象方法,因此可以被 lambda 表达式所实现。`@FunctionalInterface` 注解表示该接口是一个函数式接口,可以被用于 lambda 表达式或方法引用。
相关问题
帮忙写typescript代码,动态按需加载typescript文件中的函数方法,根据json维护的顺序动态调用函数,不同函数传值个数不同,利用原子化,返回值类型也都不同
A:
可以借助ts-node实现动态加载ts文件。具体代码如下:
```typescript
import * as ts from 'typescript';
import * as fs from 'fs';
import * as path from 'path';
interface FunctionParam {
name: string;
type?: string;
required?: boolean;
}
interface Function {
name: string;
params?: FunctionParam[];
returnType?: string;
}
function loadModule(modulePath: string, functionName: string): Function {
const code = fs.readFileSync(modulePath).toString();
const sourceFile = ts.createSourceFile(modulePath, code, ts.ScriptTarget.ESNext);
const functionDeclaration = sourceFile.statements.find((node) => {
if (!ts.isFunctionDeclaration(node)) {
return false;
}
return node.name?.escapedText === functionName;
}) as ts.FunctionDeclaration;
const functionParams = functionDeclaration.parameters.map((parameter) => {
const parameterSymbol = sourceFile.locals.get((parameter.name as ts.Identifier).escapedText);
const parameterType = parameter.type ? code.slice(parameter.type.pos, parameter.type.end) : undefined;
const parameterRequired = !(parameterQuestionToken && parameterQuestionToken.token === ts.SyntaxKind.QuestionToken);
return {
name: (parameter.name as ts.Identifier).escapedText.toString(),
type: parameterType,
required: parameterRequired,
};
});
const returnTypeSymbol = functionDeclaration.symbol?.declarations?.[0]?.type;
const returnType = returnTypeSymbol ? code.slice(returnTypeSymbol.pos, returnTypeSymbol.end) : undefined;
return {
name: functionName,
params: functionParams,
returnType,
};
}
function invokeFunction(functionModule: string, functionName: string, params: any[]): any {
const modulePath = path.resolve(__dirname, functionModule);
const functionObject = loadModule(modulePath, functionName);
// 校验参数个数
if (params.length !== (functionObject.params?.length ?? 0)) {
throw new Error('参数个数不匹配');
}
const paramObject: Record<string, any> = {};
functionObject.params?.forEach((param, index) => {
const paramValue = params[index];
// 检验参数是否必须
if (param.required && paramValue === undefined) {
throw new Error(`参数${param.name}不能为空`);
}
// 检验参数类型
if (param.type && typeof paramValue !== param.type) {
throw new Error(`参数${param.name}类型不正确,期望为${param.type}`);
}
paramObject[param.name] = paramValue;
});
const functionPath = `${modulePath}#${functionName}`;
const functionResult = invokeFunctionCache.getOrCreate(functionPath, () => {
const functionModule = require(modulePath);
const functionReference = functionModule[functionName] || functionModule.default || functionModule;
return functionReference(...params);
});
// 检验返回值类型
if (functionObject.returnType && typeof functionResult !== functionObject.returnType) {
throw new Error(`返回值类型不正确,期望为${functionObject.returnType}`);
}
return functionResult;
}
interface InvokeFunctionCacheEntry {
result: any;
timestamp: number;
}
class InvokeFunctionCache {
private readonly cache: Record<string, InvokeFunctionCacheEntry> = {};
private readonly timeout: number;
constructor(timeout?: number) {
this.timeout = timeout ?? 5000;
}
public getOrCreate(key: string, createFunc: () => any): any {
const cachedEntry = this.cache[key];
const currentTime = Date.now();
if (cachedEntry && currentTime - cachedEntry.timestamp < this.timeout) {
return cachedEntry.result;
} else {
const result = createFunc();
this.cache[key] = { result, timestamp: currentTime };
return result;
}
}
}
const invokeFunctionCache = new InvokeFunctionCache();
```
```json
[
{
"functionModule": "./function1.ts",
"functionName": "function1",
"args": [
1,
2
]
},
{
"functionModule": "./function2.ts",
"functionName": "function2",
"args": [
"hello"
]
},
]
```
```typescript
type Args = unknown[];
interface JsonFunction {
functionModule: string;
functionName: string;
args: Args;
}
function main(jsonFunctions: JsonFunction[]): void {
for (const jsonFunction of jsonFunctions) {
const {functionModule, functionName, args} = jsonFunction;
try {
const result = invokeFunction(functionModule, functionName, args);
console.log(`执行 ${functionName}(${args.join(', ')}) 结果为 ${result}`);
} catch (err) {
console.error(`执行 ${functionName}(${args.join(', ')}) 失败,原因为 ${err.message}`);
}
}
}
const jsonFunctions: JsonFunction[] = [
{
functionModule: './function1.ts',
functionName: 'function1',
args: [1, 2],
},
{
functionModule: './function2.ts',
functionName: 'function2',
args: ['hello'],
},
];
main(jsonFunctions);
```
在该代码中,我们通过loadModule函数加载ts文件,并从中获取需要执行的函数的参数数量和返回值类型等信息。然后,我们通过invokeFunction函数来执行函数,并做出必要的参数和返回值类型检查。最后,我们利用invokeFunctionCache来缓存函数的执行结果,以加快函数的重复执行速度。
最后,我们可以通过调用main函数来执行由JSON序列化的函数调用列表。
阅读全文