1. 程式人生 > 其它 >【問題】pip3連結不上python3

【問題】pip3連結不上python3

柯里化,是把接受多個引數的函式變換成接受一個單一引數(最初函式的第一個引數)的函式,並且返回接受餘下的引數而且返回結果的新函式的技術。

常用場景

  • 引數複用
  • 提前返回
  • 延遲計算/執行
// 普通的add函式
function add(x, y) {
    return x + y
}

// Currying後
function curryingAdd(x) {
    return function (y) {
        return x + y
    }
}

add(1, 2)           // 3
curryingAdd(1)(2)   // 3

常用場景

引數複用

/*
*	正常正則驗證字串 reg.test(txt)
*
*	需求:
*	驗證字串中是否含有數字或者字母
*
*/

//直接呼叫正則驗證
/\d+/g.test('hello')	   //false
/[a-z]+/g.test('hello')    //true


// 常規函式封裝
function check(reg, txt) {
    return reg.test(txt)
}

check(/\d+/g, 'hello')       //false
check(/[a-z]+/g, 'hello')    //true


// Currying  注:專案中需要多次用到規則函式時,將該函式定義為全域性函式,函式複用性更好。
function curryingCheck(reg) {
    return function(txt) {
        return reg.test(txt)
    }
}

/**
* hasNumber驗證全域性是否含有數字
* hasLetter驗證全域性是否含有字母
* hasNumber,hasLetter此時已經定義為對應的工具函式,呼叫時只需要傳遞一個引數
* 使用起來更加方便而且語義化更強,程式碼複用度更高
*
**/ 

const hasNumber = curryingCheck(/\d+/g)
const hasLetter = curryingCheck(/[a-z]+/g)

hasNumber('hello')      // false
hasLetter('hello')      // true

提前確認

/**
*
* 相容現代瀏覽器以及IE瀏覽器的事件新增方法
*
**/

//常規寫法
//問題:每次使用addEvent為元素新增事件的時候,都會判斷一次。
var addEvent = function(element, event, handler) {
    if (document.addEventListener) {
        if (element && event && handler) {
            element.addEventListener(event, handler, false);
        }
    } else {
        if (element && event && handler) {
            element.attachEvent('on' + event, handler);
        }
    }
}

//Currying 
//初始addEvent的執行其實值實現了部分的應用,而剩餘的引數應用都是其返回函式實現。
var addEvent = (function() {
    if (document.addEventListener) {
        return function(element, event, handler) {
            if (element && event && handler) {
                element.addEventListener(event, handler, false);
            }
        };
    } else {
        return function( event, handler) {
            if (element && event && handler) {
                element.attachEvent('on' + event, handler);
            }
        };
    }
})();

//不使用自啟動函式寫法

var addEvent = function() {
    const isSupport =  document.addEventListener;
    if (isSupport) {
        return function(element, event, handler) {
            if (element && event && handler) {
                element.addEventListener(event, handler, false);
            }
        }
    } else {
        return function( event, handler) {
            if (element && event && handler) {
                element.attachEvent('on' + event, handler);
            }
        };
    }
}


延遲執行

/**
*
* 函式常用的bind方法實質就是延遲執行
*
**/

Function.prototype.bind = function (context) {
    var _this = this
    var args = Array.prototype.slice.call(arguments, 1)

    return function() {
        return _this.apply(context, args)
    }
}

經典習題

// 實現一個add方法,使計算結果能夠滿足如下預期:
add(1)(2)(3)()= 6;
add(1, 2, 3)(4)() = 10;
add(1)(2)(3)(4)(5)() = 15;

// 定義引數累加方法
function  adder(...args) {
    return args.reduce( (total, currentVal) => {
        total += currentVal;
        return total;
    })
}

function addCurry(fn) {
    // _allargs  儲存所有的引數
    // _tempargs 傳遞給累加方法的複製所有引數的臨時引數
    // _tempargs 作用在收集到所有引數時使_allargs清空引數,否則重複呼叫時,_allargs會將上一次呼叫時引數與此次呼叫的引數合拼,造成錯誤的結果。
    var _allargs = [];
    var _tempargs= [];
    
    return function reFn(...args){
        if(args.length === 0){
            _tempargs = _allargs;
            _allargs = [];
            return fn.apply(this,_tempargs);
        }
        else{
            _allargs = _allargs.concat(args)
            return reFn;
        }
    }
}

console.log(add(1, 2, 3)(4)());            // 10
console.log(add(5)(6)(7)(8)(9)());         // 35


/*
* 可重複呼叫寫法
*
*  知識點:物件(包括陣列,物件,函式等)參與原始運算如算術或邏輯運算時,會無參呼叫其toString或者valueOf方法得到  *  一個原始值,然後用這個原始值參與運算。
**
*/
function add(...args) {

  // 將引數繫結到add上
  // 此時f其實還是add函式,但已經固定了一些引數,所以並不是原來的add函式
  // 用bind返回新函式以保證滿足**柯里化保留引數**的特性
  var f = add.bind(null/*this不用繫結*/, ...args) 

  // 重新實現這個bound add函式的toString方法
  // f參與運算應該被當成args的和,與f自己再接收的引數無關
  // 考慮到lazy的特性,還是需要時再計算,但又沒了快取,每次用都會重新計算
  // 如果有需要,可以改成有快取的版本
  f.toString = () => {
    return args.reduce((a, b) => a + b, 0)
  }

  return f;
}

// 考慮到add可能直接被用於運算中,可以加上這句
add.toString = () => 0


/*
 注意以上程式碼中的add,add3,add8,add8p,add9都是不同的函式,且每個函式要加的數是不一樣的。
*/
const add3  = add(0, 1)(2) // add3的功能是對傳入的數值加3並返回
console.log(  add3(2) + 0  ) // log出5
const add8  = add3(1)(2)(2) // add8由add3的持續呼叫得到
const add8p = add3(5) // 另一種方式得到add8,注意兩個add8不是同一個函式,起名add8p
const add9  = add8(1) // 由add8再傳入得到add9函式
console.log(  add9(1) + 3  ) // log出13
console.log(  add8(1) + 3  ) // log出12

參考資料

https://www.jianshu.com/p/2975c25e4d71

https://zhuanlan.zhihu.com/p/296852112