原文链接: ramda 函数 Function

上一篇: 使用 freessl.cn 为自己的静态netlify站点添加 https

下一篇: ramda 函数 Object

太多了...

去除废弃和不常用的也比rxjs多太多了

pipeWith

在管道中对每次流通的数据进行处理, 避免出现空值, 或者处理Promise

const R = require('ramda')const pipeWhileNotNil = R.pipeWith((f, res) => {console.log('=========', res, f(res))return R.isNil(res) ? res : f(res)
});
const f2 = pipeWhileNotNil([Math.pow, R.negate, R.inc,R.identity,R.dec])
console.log(f2(3, 4)
);// ========= 81 -81
// ========= -81 -80
// ========= -80 -80
// ========= -80 -81
// -81
const R = require('ramda')// 科里化函数占位符
console.log(R.divide(10, R.__)(2), // 5R.divide(R.__, 10)(2), // 0.2
)// 通过向列表迭代函数的回调函数添加两个新的参数:当前索引、整个列表,创建新的列表迭代函数。
// 例如,addIndex 可以将 R.map 转换为类似于 Array.prototype.map 的函数。
// 注意,addIndex 只适用于迭代回调函数是首个参数、列表是最后一个参数的函数。(如果列表参数没有用到,后一个条件可以忽略)。
const mapIndexed = R.addIndex(R.map);
console.log(// [ '0-f', '1-o', '2-o', '3-b', '4-a', '5-r' ]mapIndexed((val, idx) => idx + '-' + val, ['f', 'o', 'o', 'b', 'a', 'r'])
)// 返回一个返回恒定值的函数。注意,对于非原始值,返回的值是对原始值的引用。
console.log(R.always(1)()) // 1// 将 onSuccess 函数应用于一个 fulfilled Promise 的内部值,并将计算结果放入新的 Promise 中返回。
// 这对于处理函数组合内的 promises 很有用。
function getStu(name = 'abc', age = 10) {return new Promise(resolve => resolve({name, age}))
}const getStuR = R.pipe(getStu,R.andThen(R.pick(['name']))
)
getStuR('id').then(console.log) // { name: 'id' }// ap 将函数列表作用于值列表上。
// 若第二个参数自身存在 ap 方法,则调用自身的 ap 方法。柯里化函数也可以作为 applicative。
R.ap([R.multiply(2), R.add(3)], [1, 2, 3]); //=> [2, 4, 6, 4, 5, 6]
R.ap([R.concat('tasty '), R.toUpper], ['pizza', 'salad']); //=> ["tasty pizza", "tasty salad", "PIZZA", "SALAD"]// R.ap can also be used as S combinator
// when only two functions are passed
R.ap(R.concat, R.toUpper)('Ramda') //=> 'RamdaRAMDA'// 将函数 fn 作用于参数列表 args。apply 可以将变参函数转换为为定参函数。如果上下文很重要,则 fn 应该绑定其上下文。
const nums = [1, 2, 3, -99, 42, 6, 7];
R.apply(Math.max, nums); //=> 42// 接受一个属性值为函数的对象,返回一个能生成相同结构对象的函数。
// 返回的函数使用传入的参数调用对象的每个属性位对应的函数,来生成相应属性的值。
const getMetrics = R.applySpec({sum: R.add,nested: {mul: R.multiply}
});
getMetrics(2, 4); // => { sum: 6, nested: { mul: 8 } }// apply最后传入的是数据, applyTo最后传入的是函数
// 接受一个值,并将一个函数作用于其上。
// 该函数又被称为 thrush combinator.
const t42 = R.applyTo(42);
t42(R.identity); //=> 42
t42(R.add(1)); //=> 43// ascend
// 由返回值可与 < 和 > 比较的函数,创建一个升序比较函数。
const byAge = R.ascend(R.prop('age'));
const people = [{name: 'Emma', age: 70},{name: 'Peter', age: 78},{name: 'Mikhail', age: 62},
];
console.log(R.sort(byAge, people));
//=> [{ name: 'Mikhail', age: 62 },{ name: 'Emma', age: 70 }, { name: 'Peter', age: 78 }]// binary 限制函数参数个数
// 将任意元函数封装为二元函数(只接受2个参数)中。任何额外的参数都不会传递给被封装的函数。
const takesThreeArgs = function (a, b, c) {return [a, b, c];
};
takesThreeArgs.length; //=> 3
takesThreeArgs(1, 2, 3); //=> [1, 2, 3]const takesTwoArgs = R.binary(takesThreeArgs);
takesTwoArgs.length; //=> 2
// Only 2 arguments are passed to the wrapped function
takesTwoArgs(1, 2, 3); //=> [1, 2, undefined]// bind
// 创建一个绑定了上下文的函数。
// 注意:与 Function.prototype.bind 不同,R.bind 不会绑定额外参数。
const log = R.bind(console.log, console);
R.pipe(R.assoc('a', 2), R.tap(log), R.assoc('a', 3))({a: 1}); //=> {a: 3}
// logs {a: 2}// call
// 提取第一个参数作为函数,其余参数作为刚提取的函数的参数,调用该函数并将结果返回。
// R.call 可以用作 R.converge 的 convergeing 函数:第一个分支函数生成函数,其余分支函数生成一系列值作为该函数的参数。(R.converge 第二个参数为一个分支函数列表)。
R.call(R.add, 1, 2); //=> 3const indentN = R.pipe(R.repeat(' '),R.join(''),R.replace(/^(?!$)/gm));const format = R.converge(R.call, [R.pipe(R.prop('indent'), indentN),R.prop('value')
]);format({indent: 2, value: 'foo\nbar\nbaz\n'}); //=> '  foo\n  bar\n  baz\n'// comparator
// 由首个参数是否小于第二个参数的判断函数,生成一个比较函数。
const byAge3 = R.comparator((a, b) => a.age < b.age);
const people3 = [{name: 'Emma', age: 70},{name: 'Peter', age: 78},{name: 'Mikhail', age: 62},
];
const peopleByIncreasingAge = R.sort(byAge3, people3);
//=> [{ name: 'Mikhail', age: 62 },{ name: 'Emma', age: 70 }, { name: 'Peter', age: 78 }]// compose
// 从右往左执行函数组合(右侧函数的输出作为左侧函数的输入)。最后一个函数可以是任意元函数(参数个数不限),其余函数必须是一元函数。
// 注意:compose 输出的函数不会自动进行柯里化。
const classyGreeting = (firstName, lastName) => "The name's " + lastName + ", " + firstName + " " + lastName
const yellGreeting = R.compose(R.toUpper, classyGreeting);
yellGreeting('James', 'Bond'); //=> "THE NAME'S BOND, JAMES BOND"R.compose(Math.abs, R.add(1), R.multiply(2))(-4) //=> 7// composeK composeP 被 废弃了// composeWith
// 利用转换函数从右往左执行函数组合。最后一个函数可以是任意元函数(参数个数不限),其余函数必须是一元函数。
const composeWhileNotNil = R.composeWith((f, res) => R.isNil(res) ? res : f(res));
composeWhileNotNil([R.inc, R.prop('age')])({age: 1}) //=> 2
composeWhileNotNil([R.inc, R.prop('age')])({}) //=> undefined// construct constructN  构造函数科里化, 一般不太用// converge
// 接受一个 converging 函数和一个分支函数列表,返回一个新函数。
// 新函数的元数(参数个数)等于最长分支函数的元数。当被调用时,新函数接受参数,
// 并将这些参数转发给每个分支函数;然后将每个分支函数的计算结果作为参数传递给 converging 函数,
// converging 函数的计算结果即新函数的返回值。
const average = R.converge(R.divide, [R.sum, R.length])
average([1, 2, 3, 4, 5, 6, 7]) //=> 4
const strangeConcat = R.converge(R.concat, [R.toUpper, R.toLower])
strangeConcat("Yodel") //=> "YODELyodel"// curry
// 对函数进行柯里化, 允许使用占位符
const addFourNumbers = (a, b, c, d) => a + b + c + d;
const curriedAddFourNumbers = R.curry(addFourNumbers);
const f = curriedAddFourNumbers(1, 2);
const g = f(3);
g(4); //=> 10// curryN
// 对函数进行柯里化,并限制柯里化函数的元数。
const sumArgs = (...args) => R.sum(args);
const curriedAddFourNumbers2 = R.curryN(4, sumArgs);
const f2 = curriedAddFourNumbers2(1, 2);
const g2 = f2(3);
g2(4); //=> 10// descend
// 由返回值可与 < 和 > 比较的函数,创建一个降序比较函数。
const byAge4 = R.descend(R.prop('age'));
const people4 = [{name: 'Emma', age: 70},{name: 'Peter', age: 78},{name: 'Mikhail', age: 62},
];
const peopleByOldestFirst = R.sort(byAge4, people4);
//=> [{ name: 'Peter', age: 78 }, { name: 'Emma', age: 70 }, { name: 'Mikhail', age: 62 }]// 根据传入参数的类型返回其对应的空值。Ramda 定义了各类型的空值如下:
// Array ([]),Object ({}),String (''),
// 和 Arguments。empty 还支持其它定义了 <Type>.empty 、<Type>.prototype.empty
// 或 实现了 FantasyLand Monoid 规范 的类型。
// 若第一个参数自身存在 empty 方法,则调用自身的 empty 方法。
R.empty([1, 2, 3]);     //=> []
R.empty('unicorns');    //=> ''
R.empty({x: 1, y: 2});  //=> {}
console.log(R.empty({empty: () => {console.log('empty===') // empty===return 'abc'}
})); // abc// 恒定返回 false 的函数。忽略所有的输入参数。
R.F(); //=> false// flip
// 交换函数前两个参数的位置。
const mergeThree = (a, b, c) => [].concat(a, b, c);
mergeThree(1, 2, 3); //=> [1, 2, 3]
R.flip(mergeThree)(1, 2, 3); //=> [2, 1, 3]
const R = require('ramda')// identity
// 将输入值原样返回。适合用作默认或占位函数。
R.identity(1); //=> 1
const obj = {};
R.identity(obj) === obj; //=> true// invoker
// 将具有指定元数(参数个数)的具名方法,转换为可以被给定参数和目标对象直接调用的函数。
// 返回的函数是柯里化的,它接收 arity + 1 个参数,其中最后一个参数是目标对象。
// 接受参数个数 参数名称 ...参数 数据
const sliceFrom = R.invoker(1, 'slice');
console.log(sliceFrom(6, 'abcdefghijklm')); //=> 'ghijklm'
const sliceFrom6 = R.invoker(2, 'slice')(6);
console.log(sliceFrom6(8, 'abcdefghijklm')); //=> 'gh'const dog = {//speak: async () => 'Woof!'
};
const speak = R.invoker(0, 'speak');
speak(dog).then(console.log) //~> 'Woof!'// juxt 将函数列表作用于值列表。
const getRange = R.juxt([Math.min, Math.max]);
getRange(3, 4, 9, -3); //=> [-3, 9]// lift
// 提升一个多元函数,使之能映射到列表、函数或其他符合 FantasyLand Apply spec 规范的对象上。
const madd3 = R.lift((a, b, c) => a + b + c);
madd3([1, 2, 3], [1, 2, 3], [1]); //=> [3, 4, 5, 4, 5, 6, 5, 6, 7]
const madd5 = R.lift((a, b, c, d, e) => a + b + c + d + e);
madd5([1, 2], [3], [4, 5], [6], [7, 8]); //=> [21, 22, 22, 23, 22, 23, 23, 24]// liftN
// 将一个函数提升为指定元数的函数,使之能映射到多个列表、函数或其他符合 FantasyLand Apply spec 规范的对象上。
const madd33 = R.liftN(3, (...args) => R.sum(args));
madd33([1, 2, 3], [1, 2, 3], [1]); //=> [3, 4, 5, 4, 5, 6, 5, 6, 7]// memoizeWith
// 创建一个新函数,当调用时,会执行原函数,输出结果;并且缓存本次的输入参数及其对应的结果。
// 后续,若用相同的参数对缓存函数进行调用,不会再执行原函数,而是直接返回该参数对应的缓存值。
// memoizeWith 接受两个函数,第一个会将输入参数序列化为缓存键值对的“键值”,第二个是需要缓存的函数。
// 会根据第一个函数序列化的结果决定是否调用缓存函数
let count = 0;
const factorial = R.memoizeWith((i) => {console.log('i', i)return i
}, n => {count += 1;return R.product(R.range(1, n + 1));
});
factorial(5); //=> 120
factorial(5); //=> 120
factorial(5); //=> 120
console.log(count); // 1
factorial(6); //=> 720
console.log(count); // 2// nAry
// 将一个任意元(包括零元)的函数,封装成一个确定元数(参数个数)的函数。任何多余的参数都不会传入被封装的函数。
const takesTwoArgs = (a, b) => [a, b];
takesTwoArgs.length; //=> 2
takesTwoArgs(1, 2); //=> [1, 2]
const takesOneArg = R.nAry(1, takesTwoArgs);
takesOneArg.length; //=> 1
// Only `n` arguments are passed to the wrapped function
takesOneArg(1, 2); //=> [1, undefined]// nthArg
// 返回一个函数,该函数返回它的第 n 个参数。
R.nthArg(1)('a', 'b', 'c'); //=> 'b'
R.nthArg(-1)('a', 'b', 'c'); //=> 'c'// o 是一个柯里化组合函数,返回一元函数。
// 类似于 compose,o 从右到左执行函数组合。但与 compose 不同的是,传递给 o 的最右边的函数为一元函数。
const classyGreeting = name => "The name's " + name.last + ", " + name.first + " " + name.last
const yellGreeting = R.o(R.toUpper, classyGreeting);
yellGreeting({first: 'James', last: 'Bond'}); //=> "THE NAME'S BOND, JAMES BOND"
R.o(R.multiply(10), R.add(10))(-4) //=> 60// 将给定值作为元素,封装成单元素数组。
R.of(null); //=> [null]
R.of([42]); //=> [[42]]// once
// 创建一个只执行一次的函数。
// 将给定函数 fn 封装到新函数fn'中,fn' 确保 fn 只能调用一次。重复调用fn' ,只会返回第一次执行时的结果。
const addOneOnce = R.once(x => x + 1);
addOneOnce(10); //=> 11
addOneOnce(addOneOnce(50)); //=> 11// otherwise
// 将 onFailure 函数应用于一个失败 Promise 的内部值,
// 并将计算结果放入新的 Promise 中返回。这对于处理函数组合内的 rejected promises 很有用。
// 相当于 Promise 的 catch。
var failedFetch = (id) => Promise.reject('bad ID');
var useDefault = () => ({firstName: 'Bob', lastName: 'Loblaw'})//recoverFromFailure :: String -> Promise ({firstName, lastName})
var recoverFromFailure = R.pipe(failedFetch,R.otherwise(useDefault),R.andThen(R.pick(['firstName', 'lastName'])),
);
recoverFromFailure(12345).then(console.log) // { firstName: 'Bob', lastName: 'Loblaw' }// partial
// 部分应用。
// 接收两个参数:函数 f 和 参数列表,返回函数 g。当调用 g 时,将初始参数和 g 的参数顺次传给 f,并返回 f 的执行结果。
const multiply2 = (a, b) => a * b;
const double = R.partial(multiply2, [2]);
double(2); //=> 4const greet = (salutation, title, firstName, lastName) =>salutation + ', ' + title + ' ' + firstName + ' ' + lastName + '!';const sayHello = R.partial(greet, ['Hello']);
const sayHelloToMs = R.partial(sayHello, ['Ms.']);
sayHelloToMs('Jane', 'Jones'); //=> 'Hello, Ms. Jane Jones!'// partialRight 和 partial 的参数的拼接顺序不同
// 接收两个参数:函数 f 和 参数列表,返回函数 g。当调用 g 时,将 g 的参数和初始参数顺序传给 f,并返回 f 的执行结果。
const greet2 = (salutation, title, firstName, lastName) =>salutation + ', ' + title + ' ' + firstName + ' ' + lastName + '!';const greetMsJaneJones = R.partialRight(greet2, ['Ms.', 'Jane', 'Jones']);greetMsJaneJones('Hello'); //=> 'Hello, Ms. Jane Jones!'// pipe
// 从左往右执行函数组合。第一个函数可以是任意元函数(参数个数不限),其余函数必须是一元函数。
// 在一些库中,此函数也被称为 sequence。
// 注意: pipe 函数的结果不是自动柯里化的
const f = R.pipe(Math.pow, R.negate, R.inc);f(3, 4); // -(3^4) + 1// pipeP pipeK 被废弃// pipeWith
// 利用转换函数从左往右执行函数组合。第一个函数可以是任意元函数(参数个数不限),其余函数必须是一元函数。
// 注意:pipe 输出的函数不会自动进行柯里化。
const pipeWhileNotNil = R.pipeWith((f, res) => {console.log('=========')return R.isNil(res) ? res : f(res)
});
const f2 = pipeWhileNotNil([Math.pow, R.negate, R.inc])
console.log(f2(3, 4)); // -(3^4) + 1   ===  -80
console.log(f2(null, 4)); // 1
console.log(f2(4, null)); // 0
console.log(f2(null, null)); // 0
const g = R.pipeWith((f, res) => {console.log('pipe', res)return res}
)console.log(g([(name) => {console.log('name', name)return Promise.resolve(false)}])(false),R.identity,R.inc
);// T
// 恒定返回 true 的函数。忽略所有的输入参数。
R.T(); //=> true// tap
// 对输入的值执行给定的函数,然后返回输入的值。
const sayX = x => console.log('x is ' + x);
R.tap(sayX, 100); //=> 100
// logs 'x is 100'// thunkify
// 创建一个 thunk 版本的函数。 thunk 会延迟计算直到需要其结果,从而实现惰性求值。
R.thunkify(R.identity)(42)(); //=> 42
R.thunkify((a, b) => a + b)(25, 17)(); //=> 42// tryCatch 接受两个函数:tryer 和 catcher,生成的函数执行 tryer,
// 若未抛出异常,则返回执行结果。若抛出异常,则执行 catcher,返回 catcher 的执行结果。
// 注意,为了有效的组合该函数,tryer 和 catcher 应返回相同类型的值。
R.tryCatch(R.prop('x'), R.F)({x: true}); //=> true
R.tryCatch(() => {throw 'foo'
}, R.always('catched'))('bar') // => 'catched'
R.tryCatch(R.times(R.identity), R.always([]))('s') // => []
R.tryCatch(() => {throw 'this is not a valid value'
}, (err, value) => ({error: err, value}))('bar') // => {'error': 'this is not a valid value', 'value': 'bar'}// unapply
// 输入一个只接收单个数组作为参数的函数,返回一个新函数:
// 接收任意个参数;
// 将参数组成数组传递给 fn ;
// 返回执行结果。
// 换言之,R.unapply 将一个使用数组作为参数的函数,变为一个不定参函数。 R.unapply 是 R.apply 的逆函数。
R.unapply(JSON.stringify)(1, 2, 3); //=> '[1,2,3]'// unary
// 将任意元(包括零元)函数封装成一元函数。任何额外的参数都不会传递给被封装的函数。
const takesTwoArgs2 = function (a, b) {return [a, b];
};
takesTwoArgs2.length; //=> 2
takesTwoArgs2(1, 2); //=> [1, 2]const takesOneArg3 = R.unary(takesTwoArgs2);
takesOneArg3.length; //=> 1
// Only 1 argument is passed to the wrapped function
takesOneArg3(1, 2); //=> [1, undefined]// uncurryN
// 将一个柯里化的函数转换为一个 n 元函数。
const addFour = a => b => c => d => a + b + c + d;
const uncurriedAddFour = R.uncurryN(4, addFour);
uncurriedAddFour(1, 2, 3, 4); //=> 10// useWith
// 接受一个函数 fn 和一个 transformer 函数的列表,返回一个柯里化的新函数。
// 当被调用时,新函数将每个参数转发给对应位置的 transformer 函数,
// 然后将每个 transformer 函数的计算结果作为参数传递给 fn,fn 的计算结果即新函数的返回值。
// 如果新函数传传入参数的数量比 transformer 函数的数量多,
// 多出的参数会作为附加参数直接传给 fn 。如果不需要处理多出的那部分参数,
// 除了忽略之外,也可以用 identity 函数来作为 transformer ,以保证新函数的参数数量是确定的。
R.useWith(Math.pow, [R.identity, R.identity])(3, 4); //=> 81
R.useWith(Math.pow, [R.identity, R.identity])(3)(4); //=> 81
R.useWith(Math.pow, [R.dec, R.inc])(3, 4); //=> 32
R.useWith(Math.pow, [R.dec, R.inc])(3)(4); //=> 32

ramda 函数 Function相关推荐

  1. 深入理解javascript中的立即执行函数(function(){…})()

    2019独角兽企业重金招聘Python工程师标准>>> javascript和其他编程语言相比比较随意,所以javascript代码中充满各种奇葩的写法,有时雾里看花,当然,能理解各 ...

  2. js立即执行函数: (function ( ){...})( ) 与 (function ( ){...}( ))

    ( function(){-} )() ( function (){-} () ) 是两种javascript立即执行函数的常见写法,最初我以为是一个括号包裹匿名函数,再在后面加个括号调用函数,最后达 ...

  3. Python编程基础:第二十节 函数Function

    第二十节 函数Function 前言 实践 前言 目前为止,我们已经学习了常见的数据类型以及逻辑结构.但是代码都只能运行一次,如果想多次运行该段代码就得重复写多次.为了避免书写冗余的代码,我们需要引入 ...

  4. Golang 函数function

    函数function Go函数不支持嵌套.重载和默认参数 但支持以下特性: 无需声明原型 不定长度变参 多返回值 命名返回值参数 匿名函数 闭包 定义函数使用关键字func,且左大括号不能另起一行 函 ...

  5. JS-立即执行函数(function(){...})() amp;amp; (function(){...})()

    在学习闭包的过程中遇到了(立即执行),之前见到(function(){...})() && (function(){...}())这种写法,就没有去知其所以然,也不会去写这种函数.所以 ...

  6. 数据库系列之mysql 自定义函数function,函数和存储过程的区别

    mysql 自定义函数function,函数和存储过程的区别 https://blog.csdn.net/u010365819/article/details/80470448 https://blo ...

  7. JS:1.3,函数(function)

    ylbtech-JS:函数-导航 函数定义 返回函数 调用一个函数 调用一个函数(带参数) 返回值的函数 调用外部的js文件 JS:3.1,函数(function)-定义 返回顶部 1,定义函数语法 ...

  8. C语言试题五十七之假定输入的字符串中只包含字母和*号。请编写函数function,它的功能是:删除字符串中所有*号。在编写函数时,不得使用c语言提供的字符串函数。

    1. 题目 假定输入的字符串中只包含字母和*号.请编写函数function,它的功能是:删除字符串中所有*号.在编写函数时,不得使用c语言提供的字符串函数. 2 .温馨提示 C语言试题汇总里可用于计算 ...

  9. C语言试题五十五之m个人的成绩存放在score数组中,请编写函数function,它的功能是:将高于平均分的人数作为函数值返回,将高于平均分的分数放在high所指定的数组中。

    1. 题目 m个人的成绩存放在score数组中,请编写函数function,它的功能是:将高于平均分的人数作为函数值返回,将高于平均分的分数放在high所指定的数组中. 2 .温馨提示 C语言试题汇总 ...

  10. C语言试题四十七之程序定义了N×M的二维数组,并在主函数中自动赋值。请编写函数function(int a[N][M], int m),该函数的功能是:将数组右上半三角元素中的值乘以m。

    1. 题目 程序定义了N×M的二维数组,并在主函数中自动赋值.请编写函数function(int a[N][M], int m),该函数的功能是:将数组右上半三角元素中的值乘以m. 2 .温馨提示 C ...

最新文章

  1. .NET简谈脚本引擎系列(一:认识脚本引擎)
  2. java 堆栈 对象_在Java中,哪些对象放在堆栈上,哪些放在堆上?
  3. 乐鑫代理启明云端分享|ESP32驱动1.54inch(240*240)彩屏
  4. 【MFC】状态栏随对话框的改变而改变
  5. 超出部分用省略号显示 以及 bootStrapTable 的属性一览表
  6. KubeVela 高可扩展的云原生应用平台与核心引擎
  7. 【Linux】linux服务器下包管理器
  8. python3 random模块_Python3 中 random模块
  9. python 查看数据结构类型_python 数据结构类型总结(示例代码)
  10. [jQuery基础] jQuery事件相关
  11. 未来的商业,一定是基于在线化的
  12. php swoole扩展,php如何安装swoole扩展
  13. textarea去掉滚动条
  14. python实现程序自动运行的库_python tkiner实现自动打包程序
  15. everedit选择_everedit快捷键
  16. 关于Chrome浏览器设置启用Flash插件
  17. ABBYY FineReader 14创建PDF文档功能解析
  18. 银河麒麟V10操作系统修改屏幕分辨率
  19. java代码质量 圈复杂度,代码圈复杂度(Cyclomatic Complexity,CC)和Oclint工具 介绍...
  20. 论坛议程|COSCon'22 云计算(C)

热门文章

  1. 九月十月百度人搜,阿里巴巴,腾讯华为笔试面试八十题(第331-410题)
  2. 怎么让模糊的数字变清楚_如何用ps将模糊图片变清晰?
  3. Linux7安装oracle11g报错 Error in invoking target 'agen
  4. 打太极不协调的二三事
  5. 市场车载音响麦克风摆放以及降噪解决方案
  6. Golang 中map与GC“纠缠不清”的关系
  7. 董明珠的“三个谜团”
  8. word中插入分割线
  9. 关于git的安装与配置问题
  10. 在Windows系统中安装Go语言