python go 延遲呼叫的多個閉包捕獲同一變數的問題
def mult():
return [lambda x : x * i for i in range(4)]
for ele in mult():
print(ele(2))
lambda 先捕獲上下文環境中的變數構成可呼叫物件,真正的呼叫在後邊顯式的呼叫處。問題在於 lambda 捕獲的是變數的引用(一個地址對應的記憶體),而不是捕獲時,變數的值,實際上這個值在捕獲之後可以被修改。所以實際上 3 個 lambda 捕獲的是同一個 i,i 最終對應的值為 3.
x = 3
f = lambda y : x * y
f(4)
x = 4
f(4)
第一次輸出 12,第二次輸出 16,再看上邊的問題,最終將輸出
6
6
6
6
解決的辦法就在於新增一個臨時的變數:
def mult():
return [lambda x, y = i : x * y for i in range(4)]
for ele in mult():
print(ele(2))
此時,便能輸出:
0
2
4
6
go 的匿名函式同樣有這個問題:
func main() { var s []func(int) int for i := 0; i < 4; i++ { s = append(s, func(x int) int{ return x * i }) } for _, f := range s{ fmt.Println(f(2)) } }
小差異:跳出迴圈時,i 的值是 4;而在 python 的列表生成式 for i in range(4) 當中,迭代停止時,i 的值是 3. 所以此處 go 的輸出為:
8
8
8
8
解決辦法一樣是新增臨時變數:
func main() {
var s []func(int) int
for i := 0; i < 4; i++ {
j := i
s = append(s, func(x int) int{
return x * j
})
}
for _, f := range s{
fmt.Println(f(2))
}
}
此時可以得到想要的結果:
0
2
4
6
實際上根據詞法作用域,新增的臨時變數可以直接取名為 i,此時的 i 將遮蔽外層作用域的 i.
總結:python 和 go 中的匿名函式的捕獲都是引用語義上的捕獲(go本身只有值語義,map,slice,chan 說是傳引用,實質只是一個淺拷貝而已),所以捕獲的變數在被捕獲之後在匿名函式外被修改,匿名函式將受影響。
題外話,因為 C++ 中的 lambda 同時支援值捕獲和引用捕獲兩種方式,而按值捕獲,捕獲的變數的值就是捕獲的當時變數的值,這個值捕獲之後將不受外邊作用域的影響。當然不加 mutable 修飾,這個不過的變數在 lambda 內部也不能被修改。
uint32_t i = 0;
auto f = [i]() mutable
{
std::cout << "in f : " << i << "\n";
++i;
};
++i;
f();
std::cout << "after f : " << i << "\n";
相關推薦
python go 延遲呼叫的多個閉包捕獲同一變數的問題
def mult(): return [lambda x : x * i for i in range(4)] for ele in mult(): print(ele(2)) lambda 先捕獲上下文環境中的變數構成可呼叫物件,真正的呼叫在後邊顯式的呼叫處。問題在於
Python呼叫多個jar包by jpype
最近在看如何接入java的API 很多文章介紹了jpype。接入API後還想知道如何接入兩個或多個jar包,結果網上似乎沒有查到。自己試過之後發現只要這麼做就可以了:if __name__ == "__main__": jarpath=os.path.join(os.
go語音基礎之閉包捕獲外部變數特點
1、閉包捕獲外部變數特點 示例: package main //必須 import "fmt" func main() { a := 10 str := "mike" func() { //閉包以引用方式捕獲外部變數 a = 666 str = "go"
Python刪除list中多個相同元素
個人 err val pos 倒序 pan move 信息 style pop和remove方法都可以刪除list中的元素,個人更傾向於使用remove方法,因為在刪除過程中不會打印信息,安靜的把任務完成。 pop方法:刪除過程中會打印信息 >>>
Python--函數return多個值
列表推導式 int abc log gpo new 方法 post 函數 # 函數如果有多個return值,那麽會把這幾個return值放到一個元組裏面返回 # def hello(a, b, c, d):# return a, b, c, d## res = he
Python 基礎第十一天(閉包和裝飾器初識)
過程 理解 繼續 記錄 turn 格式 -s pos 變量賦值 今日內容: 函數名的應用 閉包 裝飾器的初識 裝飾器的傳參 1.函數名的應用 函數名是函數的名字. 本質:變量,特殊的變量。是函數的內存地址 函數名() 可以執行此函數 (1)單獨打印函數名,可以得到函數的內存
python 第3章 之三 閉包,模塊等
python閉包&LEGB法則所謂閉包,就是將組成函數的語句和這些語句的執行環境打包在一起時,得到的對象 聽上去的確有些復雜,還是用一個栗子來幫助理解一下。假設我們在foo.py模塊中做了如下定義:#foo.pyfilename = "foo.py" def call_func(f
簡簡單單說個閉包
無法 服務 AR 編程語言 函數式 outer 但是 min 概念 閉包的作用 一句話,閉包的作用:將方法存於變量。 至於閉包的原因或者目的,或者說,為什麽將方法存於變量,稍後再說。 閉包的條件 為了盡量避免用一大段話描述一個概念,我們理性一點地把閉包的條件劃分成3個:
python 推導式中多個if else 問題
count int 列表 foo sta ood food 別人 輸出 lis03=[[[‘food‘,‘feed‘,‘foot‘],‘good‘,[‘look‘,‘loof‘,‘like‘],‘book‘],[‘cool‘,‘our‘,‘you‘,‘how‘]]有這樣一個
13、python中的函數(閉包與裝飾器)
屬性 新的 做的 一個 too 實現 inf 高級 器) 一、嵌套函數 函數的內部又再定義另一個函數,這個函數就叫嵌套函數,裏面含函數就叫內部函數。 示例: 二、返回函數 函數可以接收函數對象作為參數,同理函數也能返回一個函數對象作為返回值。
python函數名的運用,閉包,叠代器
exce 耗時 inner 同時 選擇 rabl 器協 iterable from 一.函數名的運用 函數名是一個變量,但它是一個特殊的變量,與括號配合可以執行函數的變量. 1.函數名的內存地址 1 def func(): 2 print("呵呵") 3 pr
用Jenkins集成ios項目設置多scheme,同一代碼自動輸出多個環境包 實現便捷切換API環境
ios項目 bug 編譯打包 不同配置 online space 測試 jenkin spa Jenkins 安裝使用參考我的博客http://www.cnblogs.com/zhujin/p/9064820.html Xcode 配置:說明 一個schema 對應一套環境
UVALive-7197 Axles 動態規劃 多個背包問題
uva main uvalive spa %d val 好題 ble 更改 題目鏈接:https://cn.vjudge.net/problem/UVALive-7197 題意 需要生產n種(2<=n<=14)零件,每種零件可以用兩種材料制作,對這兩種材料的消耗
python函數嵌套以及閉包的原理
一點 才會 解析器 http 標識 -- return 將不 定義 變量相關—嵌套函數 python允許創建嵌套函數。也就是說我們可以在函數裏面定義函數,而且現有的作用域和變量生存周期依舊不變。 例子: #encoding=utf-8def outer(): name
利用python腳本把多個文件內容放到一個文件內
tdi con linux 文件內容 內容 with open pytho xls code 說明:path是你所有文件存放的目錄,先去循環所有的文件內容,然後寫入到test.xls文件裏 import os path = ‘file‘ # path=r‘D:\file‘
PYTHON自動化Day6-函式多個返回值和匿名函式、列表生成式,三元運算子,os模組,sys模組,時間模組,字典排序,資料庫操作,加密(md5)
一.函式多個返回值和匿名函式 #函式返回多個值,用一個變數接收 def say(): num1=1 num2=2 num3=3 return num1,num2,num3 res=say() print(res) #打印出來是元組。 函式如果返回多個值的話,會把返回的
用Python指令碼自動運營多個自媒體平臺,不寫稿坐等收錢,只告訴你原理
使用此方法最低成本不超過120元/年,年收入根據你所選擇垂直行業和帳號多少以及哪些平臺來決定 我所說的最低成本是針對我而言來說的,辛苦點的可以做到0成本操作,喜歡冒險的總投入不會超過5000塊錢 首先第一步就是你要有自媒體帳號,帳號和平臺不限,根據你對平臺的理解來自行選擇使用那個平臺,
python基礎知識整理4——函式閉包
函式閉包 Function Clouse:引用了自由變數的函式既是一個閉包.這個被引用的自由變數和這個函式一同存在,即便它已經離開了創造它的環境也一樣. 比如下面的函式的返回值 def foo(): I = [] def bar(i): I.appe
Android同一套程式碼打多個APP包並能夠在同一個手機上安裝執行
Android同一套程式碼打多個APP包並能夠在同一個手機上安裝執行 Android同一套程式碼打多個APP包並能夠==在同一個手機上安裝執行==,同時==APP名稱、桌面icon圖示也都不同== 給同一套程式碼起不同的多個包名,並把APP名稱和桌面圖示設定為
在當java有多個jar包和多個檔案時,如何在控制檯編譯執行
編譯 javac -cp .:/root/java/hash2/lib/mysql-connector-java-5.1.35-bin.jar:/root/java/hash2/lib/c3p0-0.9.1.1.jar *.java 執行 java -cp .: