当前位置: 首页 > 编程日记 > 正文

colsure php_PHP Closure(闭包)类详解

闭包就是能够读取其他函数内部变量的函数。例如在javascript中,只有函数内部的子函数才能读取局部变量,所以闭包可以理解成“定义在一个函数内部的函数“。在本质上,闭包是将函数内部和函数外部连接起来的桥梁。 在php中,闭包函数一般就是匿名函数.

Closure

面向对象变成语言代码的复用主要采用继承来实现,而函数的复用,就是通过闭包来实现。这就是闭包的设计初衷。

注:PHP里面闭包函数是为了复用函数而设计的语言特性,如果在闭包函数里面访问指定域的变量,使用use关键字来实现。

PHP具有面向函数的编程特性,但是也是面向对象编程语言,PHP 会自动把闭包函数转换成内置类 Closure 的对象实例,依赖Closure 的对象实例又给闭包函数添加了更多的能力。

闭包不能被实例(私有构造函数),也不能被继承(finally 类)。可以通过反射来判断闭包实例是否能被实例,继承。

匿名函数

匿名函数,是php5.3的时候引入的,又称为Anonymous functions。字面意思也就是没有定义名字的函数。

提到闭包就不得不想起匿名函数,也叫闭包函数(closures),貌似PHP闭包实现主要就是靠它。声明一个匿名函数是这样:

$say =function() {return '我是匿名函数';

};//带结束符

echo $say();//这是最直接调用匿名函数方式

function test(Closure $callback)

{ return $callback();}

echo test($say);//这是间接调用匿名函数方式

当然也可以这样写 :

echo test( function() {

return '我是匿名函数';

});

//例一

//在函数里定义一个匿名函数,并且调用它

function printStr() {

$func = function( $str ) {

echo $str;

};

$func( 'some string' );

}

printStr();

//例二

//在函数中把匿名函数返回,并且调用它

function getPrintStrFunc() {

$func = function( $str ) {

echo $str;

};

return $func;

}

$printStrFunc = getPrintStrFunc();

$printStrFunc( 'some string' );

//例三

//把匿名函数当做参数传递,并且调用它

function callFunc( $func ) {

$func( 'some string' );

}

$printStrFunc = function( $str ) {

echo $str;

};

callFunc( $printStrFunc );

//也可以直接将匿名函数进行传递。如果你了解js,这种写法可能会很熟悉

callFunc( function( $str ) {

echo $str;

} );

可以看到,匿名函数因为没有名字,如果要使用它,需要将其返回给一个变量。匿名函数也像普通函数一样可以声明参数,调用方法也相同:

$func =function( $param ) {

echo $param;

};

$func('some string');//输出://some string

顺便提一下,PHP在引入闭包之前,也有一个可以创建匿名函数的函数:create function,但是代码逻辑只能写成字符串,这样看起来很晦涩并且不好维护,所以很少有人用。

实现闭包

将匿名函数在普通函数中当做参数传入,也可以在函数中被返回。这就实现了一个简单的闭包。

连接闭包和外界变量的关键字:USE

PHP在默认情况下,匿名函数不能调用所在代码块的上下文变量,而需要通过使用use关键字。

function getMoney() {

$rmb= 1;

$func=function() use ( $rmb ) {

echo $rmb;//把$rmb的值加1

$rmb++;

};

$func();

echo $rmb;//闭包内的变量改变了,但是闭包外没有改变。

}

getMoney();//输出://1//1

在上面我们看见匿名函数不能改变上下文的变量,是因为use所引用的也只不过是变量的一个副本clone而已(非完全引用变量本身)。

如果我们想在匿名函数中改变上下文的变量呢?想要完全引用变量,而不是复制呢?要达到这种效果,在变量前加一个 & 符号即可。

function getMoney() {

$rmb= 1;

$func= function() use ( &$rmb ) {

echo $rmb;//把$rmb的值加1

$rmb++;

};

$func();

echo $rmb;

}

getMoney();//输出://1//2

好,这样匿名函数就可以引用上下文的变量了。如果将匿名函数返回给外界,匿名函数会保存use所引用的变量,而外界则不能得到这些变量,这样形成‘闭包’这个概念可能会更清晰一些。

根据描述我们再改变一下上面的例子:

function getMoneyFunc() {

$rmb= 1;

$func= function() use ( &$rmb ) {

echo $rmb.'
';//把$rmb的值加1

$rmb++;

};return$func;

}

$getMoney= getMoneyFunc(); //匿名函数返回给外界,保存了$rmb的变量

$getMoney();

$getMoney();

$getMoney();//输出://1//2//3从例子中理解“将匿名函数返回给外界,匿名函数会保存use所引用的变量,而外界则不能得到这些变量”,将匿名函数返回给外界后,$rmb这个引用变量就被保存了,提升成了全局变量(全局变量,类似静态变量),而后面每次再调用匿名函数,传入的都是这个保存后的值

总结:

闭包函数不能直接访问闭包外的变量,而是通过use 关键字来调用上下文变量(闭包外的变量),也就是说通过use来引用上下文的变量;

闭包内所引用的变量不能被外部所访问(即,内部对变量的修改,外部不受影响),若想要在闭包内对变量的改变从而影响到上下文变量的值,需要使用&的引用传参。

use所引用的是变量的复制(副本而),并不是完全引用变量。如果要达到引用的效果,就需要使用 & 符号,进行引用传递参数;

如果我们要调用一个类里面的匿名函数呢?直接上demo

return $i+100;

};

}

}

function B(Closure $callback)

{return $callback(200);

}

$a=B(A::testA());

print_r($a);//输出 300

其中的A::testA()返回的就是一个无名funciton。

绑定的概念

上面的例子的Closure只是全局的的匿名函数,好了,那我们现在想指定一个类有一个匿名函数。也可以理解说,这个匿名函数的访问范围不再是全局的了,而是一个类的访问范围。

那么我们就需要将“一个匿名函数绑定到一个类中”。

PHP Closure 类是用于代表匿名函数的类,匿名函数(在 PHP 5.3 中被引入)会产生这个类型的对象,Closure类摘要如下:

Closure {

__construct (void)public static Closure bind (Closure $closure , object $newthis [, mixed $newscope = 'static'])public Closure bindTo (object $newthis [, mixed $newscope = 'static'])

}

参数说明:

closure

需要绑定的匿名函数。

newthis

需要绑定到匿名函数的对象,或者 NULL 创建未绑定的闭包。

newscope

想要绑定给闭包的类作用域,或者 'static' 表示不改变。如果传入一个对象,则使用这个对象的类型名。 类作用域用来决定在闭包中 $this 对象的 私有、保护方法 的可见性。(备注:可以传入类名或类的实例,默认值是 'static', 表示不改变。)

返回值:

返回一个新的 Closure 对象 或者在失败时返回 FALSE

方法说明:

Closure::__construct — 用于禁止实例化的构造函数

Closure::bind — 复制一个闭包,绑定指定的$this对象和类作用域。

Closure::bindTo — 复制当前闭包对象,绑定指定的$this对象和类作用域。

除了此处列出的方法,还有一个 __invoke 方法。这是为了与其他实现了 __invoke()魔术方法 的对象保持一致性,但调用闭包对象的过程与它无关。

Closure::bind是Closure::bindTo的静态版本

深入理解bind参数:

要理解bing参数,先要理解类属性的可访问权限 public,private(子类不可访问),protect(子类可访问,类外不可以访问)。

php的public、protected、private三种访问控制模式的区别

public: 公有类型 在子类中可以通过self::var调用public方法或属性,parent::method调用父类方法

在实例中可以能过$obj->var 来调用 public类型的方法或属性

protected: 受保护类型在子类中可以通过self::var调用protected方法或属性,parent::method调用父类方法

在实例中不能通过$obj->var 来调用 protected类型的方法或属性

private: 私有类型该类型的属性或方法只能在该类中使用,在该类的实例、子类中、子类的实例中都不能调用私有类型的属性和方法

不能通过 $this 访问静态变量,静态方法里面也不可用 $this (原因:静态属性属于类本身而不属于类的任何实例。静态属性可以被看做是存储在类当中的全局变量,可以在任何地方通过类来访问它们)

在类外不能通过 类名::私有静态变量,只能在类里面通过self,或者static 访问私有静态变量:

第一个参数:需要绑定的匿名函数。

第二个参数:关于bind的第二个参数为object还是null,取决于第一个参数闭包中是否用到了`$this`的上下文环境。(绑定的对象决定了函数中的$this的取值)

若闭包中用到了`$this`,则第2个参数不可为null,只能为object实例对象;若闭包中用到了静态访问(::操作符),第2个参数就可以为null,也可以为object

第三个参数(作用域):是控制闭包的作用域的,如果闭包中访问的是 private 属性,就需要第3个参数提升闭包的访问权限,若闭包中访问的是public属性,第三个参数可以不用。只有需要改变访问权限时才要,传对象,类名都可以。

[bind的第三个参数:mixed类型的类作用域,决定了这个匿名函数中能够调用哪些私有和保护的方法。也就是说this可以调用的方法,即这个this可以调用的方法,即这个this可以调用的方法与属性,与这个scope一致。

第三个参数如果是类实例对象与类的名称都代表着这个闭包有类作用域,如果是static则表示这个闭包与外部变量作用域一样,不能访问类的私有以及保护方法。

mixed类型在PHP中也就是没有类型限定的意思,缺省情况下第三个参数是个字符串,值是‘static’]

第2个参数是给闭包绑定`$this`对象的,第3个参数是给闭包绑定作用域的。

通过成员的可访问行来举例子理解:

classA{private $name = '王力宏';protected $age = '30';private static $weight = '70kg';public $address = '中国';public static $height = '180cm';

}

$obj = newA();//echo $obj->name;//报错 Cannot access private property A::$name//echo $obj->age;//报错 Cannot access protected property A::$age//echo A::$weight;//报错 Cannot access private property A::$weight

echo $obj->address;//正常 输出 中国

echo A::$height;//正常 输出 180cm

$fun =function(){

$obj= newA();return $obj->address;//实例对象可以获得公有属性, $obj->name等私有属性肯定不行 上面例子已列出报错

}

echo $fun();//正常 输出 中国

$fun2 =function(){return A::$height;//类可以直接访问公有静态属性,但A::$weight肯定不行,因为weight为私有属性

}

echo $fun2();//正常 输出 180cm

以上都理解的情况下 我们来看看这样的情况,有如下匿名函数:

$fun =function(){return $this->name;

}

或者

$fun=function(){returnA::$height;

}

echo $fun();//会报错的

其实单独这段代码是肯定不能运行 调用的,因为里面有个$this,程序压根不知道你这个$this是代表那个对象 或 那个类(并且就算知道那个对象或类,该对象是否拥有name属性,如果没有照样会有问题)

因此想让其正常运行肯定有前提条件啊(就好比你想遍历某个数组一样,如果这个数组压根你就没提前定义 声明 肯定会报错的)

如果这样:

$fun =function(){//name是私有属性,需要第3个参数

return $this->name;

} ;

$name= Closure::bind($fun,new A() ,'A');

echo $name();//输出 王力宏

该函数返回一个全新的 Closure匿名的函数,和原来匿名函数$fun一模一样,只是其中$this被指向了A实例对象,这样就能访问address属性了。

使用了bind函数后 ,

其实是匿名函数里的$this被指定到了或绑定到了A实例对象上了

Closure::bind($fun,newA() );

这个使用 你可以理解成对匿名函数做了如下过程:

$fun=function(){

$this = newA();return $this->name;

} ;

你可以想象认为,$this就成了A类的实例对象了,然后在去访问name属性,就和我们正常实例化类访问成员属性一样,上面2中的例子$obj = new A()就是这样,(因为$this是关键字,在这里我们其实不能直接$this = new A();这么写,为了好理解我写成$this,但是原理还是这个意思),但是我们都知道因为name属性是私有的,上面2中我已说过,实例对象不能访问私有属性,那该怎么办呢,于是添加第三个参数就很重要了,一般传入传入一个对应对象,或对应类名(对应的意思是:匿名函数中$this-name想获取name属性值,你这个$this想和那个类和对象绑定在一起呢,就是第二个参数,这时你第三个参数写和第二个参数写一样的对象或类就行了,就是作用域为这个对象或类,这就会让原理的name私有属性变为公有属性)

$fun =function(){//address为公开,第3个参数可以不需要

return $this->name;

} ;

$address= Closure::bind($fun,newA());

echo $address();

这里数一下bind这次为什么没添加第三个参数,因为我们要访问的address属性是公有的,一个对象实例是可以直接访问公有属性的,这个例子中只要匿名函数中$this被指向了A对象实例(或者叫绑定也可以),就能访问到公有属性,所以可以不用添加第三个参数,当然你加上了第三个参数 如这样Closure::bind($fun2, new A(), ‘A’ );或Closure::bind($fun2, new A(), nwe A() );不影响 照样运行,就好比把原来公有属性 变为公有属性 不影响的(一般当我们访问的属性为私有属性时,才使用第三个参数改变作用域 ,使其变为公有属性)

$fun =function() {//访问私有静态属性,访问静态属性,第2个参数可以为null,访问私有属性,需要第3个参数提高作用域//return A::$weight; 这样写,会报错,提示不能通过类名访问私有静态变量//weight 为类的私有属性,只可在类中访问  return self::$weight;

};

//echo $fun(); 运行会报错 因为weight为私有属性 。

$weight = Closure::bind($fun,null,'A');//通过bind函数作用,返回一个和$fun匿名函数一模一样的匿名函数,只是该匿名函数中A::$weight, weight属性由私有变成公有属性了。

echo $weight();

为什么第二个参数又成null了呢,因为在该匿名函数中A::$weight 这属于正常类使用啊(php中 类名::公有静态属性,这是正常访问方法,上面2中例子已经说的很清楚了),所以不用绑定到某个对象上去了,于是第二个参数可以省略,唯一遗憾的是weight属性虽是静态属性,但是其权限是private私有属性,于是我们要把私有属性变公有属性就可以了,这时把第三个参数加上去就可以了,第三个参数可以是A类(Closure::bind($fun,null,'A')),也可以是A类的对象实例(Closure::bind($fun,null, new A() )),两种写法都可以,最终第三个参数的添加使私有属性变成了公有属性,(这个例子中当然你非得添加第二个参数肯定也没问题,只要第二个参数是A的实例对象就行Closure::bind($fun,new A(),'A'),不影响,只是说 A::$weight 这种使用方法本身就是正常使用,程序本身就知道你用的是A类,你在去把它指向到A类自己的对象实例上,属于多此一举,因此第二个参数加不加都行,不加写null就行)

综上大家应该理解其用法了吧,有时第二个参数为null,有时第三个参数可以不要,这些都跟你匿名函数里 代码中访问的方式紧密相关

总结:

1、一般匿名函数中有$this->name类似这样用 $this访问属性方式时,你在使用bind绑定时 ,第二个参数肯定要写,写出你绑定那个对象实例,第三个参数要不要呢,要看你访问的这个属性,在绑定对象中的权限属性,如果是private,protected 你要使用第三个参数 使其变为公有属性, 如果本来就是公有,你可以省略,也可以不省略

2、一般匿名函数中是 类名::静态属性 类似这样的访问方式(比如例子中A::$weight),你在使用bind绑定时,第二个参数可以写null,也可以写出具体的对象实例,一般写null就行(写了具体对象实例多此一举),第三个参数写不写还是得看你访问的这个静态属性的权限是 private 还是 public,如果是私有private或受保护protected的,你就得第三个参数必须写,才能使其权限变为公有属性 正常访问,如果本来就是公有public可以不用写,可以省略

3、需要提升属性作用域时,第3个参数需要传,传对象或者类名都可以。

例子:

classAnimal {public $cat = 'cat';public static $dog = 'dog';private $pig = 'pig';private static $duck = 'duck';

}//不能通过 $this 访问静态变量//不能通过 类名::私有静态变量,只能通过self,或者static,在类里面访问私有静态变量

$cat=function() {return $this->cat;

};

$dog= staticfunction () {returnAnimal::$dog;

};

$pig=function() {return $this->pig;

};

$duck= staticfunction() {//return Animal::$duck; 这样写,会报错,提示不能通过类名访问私有静态变量

return self::$duck; //return static::$duck

};

$bindCat= Closure::bind($cat, new Animal(), 'Animal');

$bindCat2= Closure::bind($cat, new Animal(), newAnimal());

echo $bindCat() . PHP_EOL;

echo $bindCat2() . PHP_EOL;

$bindDog= Closure::bind($dog, null, 'Animal');

$bindDog2= Closure::bind($dog, null, newAnimal());

echo $bindDog() . PHP_EOL;

echo $bindDog2() . PHP_EOL;

$bindPig= Closure::bind($pig, new Animal(), 'Animal');

$bindPig2= Closure::bind($pig, new Animal(), newAnimal());

echo $bindPig() . PHP_EOL;

echo $bindPig2() . PHP_EOL;

$bindDuck= Closure::bind($duck, null, 'Animal');

$bindDuck2= Closure::bind($duck, null, newAnimal());

echo $bindDuck() . PHP_EOL;

echo $bindDuck2() . PHP_EOL;

通过上面的例子,可以看出函数复用得,可以把函数挂在不同的类上,或者对象上。

闭包函数的应用:

/**

* 一个基本的购物车,包括一些已经添加的商品和每种商品的数量

**/

classCart {//定义商品价格

const PRICE_BUTTER = 10.00;const PRICE_MILK = 30.33;const PRICE_EGGS = 80.88;protected $products =array();/**

* 添加商品和数量

*

* @access public

* @param string 商品名称

* @param string 商品数量*/

publicfunction add($item, $quantity) {

$this->products[$item] =$quantity;

}/**

* 获取单项商品数量

*

* @access public

* @param string 商品名称*/

publicfunction getQuantity($item) {return isset($this->products[$item]) ? $this->products[$item] : FALSE;

}/**

* 获取总价

*

* @access public

* @param string 税率*/

publicfunction getTotal($tax) {

$total= 0.00;

$callback= function ($quantity, $item) use ($tax, &$total) {

$pricePerItem= constant(__CLASS__ . "::PRICE_" . strtoupper($item)); //调用以上对应的常量

$total += ($pricePerItem * $quantity) * ($tax + 1.0);

};

array_walk($this->products, $callback);return round($total, 2);

}

}

$my_cart= newCart;//往购物车里添加商品及对应数量

$my_cart->add('butter', 10);

$my_cart->add('milk', 3);

$my_cart->add('eggs', 12);//打出出总价格,其中有 3% 的销售税.

echo $my_cart->getTotal(0.03);//输出 1196.4

给类的私有属性赋值:

classA {private $attr =array();

}classB {public staticfunction bind (A $a) {return\Closure::bind(function () use ($a) {//给私有属性赋值

$a->attr =['color' => 'red','weight' => '1.0',

];

},null, A::class);

}

}//我们在对象外部给私有对象赋值时,需要通过\Closure::bind ,来提高闭包作用域进行赋值

$a = newA();//不能对私有属性直接进行$a->attr = ['color' => 'red','weight' => '1.0'];

call_user_func(B::bind($a));

print_r($a);

通过上面的几个例子,其实匿名绑定的理解就不难了....我们在看一个扩展的demo(引入trait特性)

给类动态的添加方法

/**

* 给类动态添加新方法

*

* @author fantasy*/trait DynamicTrait {/**

* 自动调用类中存在的方法*/

publicfunction __call($name, $args) {if(is_callable($this->$name)){ //getdog函数在__set已经定义和绑定了return call_user_func($this->$name, $args); //把第一个参数作为回调函数调用

}else{throw new \RuntimeException("Method {$name} does not exist");

}

}/**

* 添加方法*/

publicfunction __set($name, $value) {

$this->$name = is_callable($value)?$value->bindTo($this, $this):$value;

//相当于 $getdog = function(){ return $this->dog; } Closure::bindto($getdog, new Animal,'Animal');

}

}/** * 只带属性不带方法动物类 * * @author fantasy*/

classAnimal {

use DynamicTrait;private $dog = '汪汪队';

}

$animal= newAnimal;//往动物类实例中添加一个方法获取实例的私有属性$dog

$animal->getdog =function() {return $this->dog; };

echo $animal->getdog();//输出 汪汪队

获取类属性:第3个参数 score 范围 设置为null 时,只能获取到 public 属性。

如果希望完全取消绑定,则需要将闭包和范围都设置为null

classMyClass

{public $foo = 'a';protected $bar = 'b';private $baz = 'c';/**

* @param bool $all 是否获取全部的属性

*

* @return array*/

public function toArray($all = false)

{//Only public variables

$callback =(function ($obj) {//get_object_vars — 返回由对象属性组成的关联数组 ,在类内调用时,会返回所有的属性(private,protect,public), 在类外使用只返回public

returnget_object_vars($obj);

});//指定作用域 为 null 则会返回 public 属性; 指定作用域默认 ‘static’,则会返回所有属性

if($all) {

$callback= $callback->bindTo(null); //只能在类里面通过self,或者static 访问私有静态变量

}else{//类内获取public属性

$callback = $callback->bindTo(null, null);

}return $callback($this);

}

}

$obj = new MyClass;

$vars = get_object_vars($obj); // get_object_vars 类外使用,获取到的是 public 属性

print_r($vars);

echo '
';

$vars = $obj->toArray();

print_r($vars);

echo '
';

$vars = $obj->toArray(1);

print_r($vars);

结果:

Array ( [foo] =>a )

Array ( [foo]=>a )

Array ( [foo]=> a [bar] => b [baz] => c )

总结:

1. 闭包内如果用 $this, 则 $this 只能调用非静态的属性,这和实际类中调用原则是一致的,且 Closure::bind() 方法的第2个参数不能为null,必须是一个实例 (因为$this,必须在实例中使用),第三个参数可以是实例,可以是类字符串,或 static;

2. 闭包内调用静态属性时,闭包必须声明为 static,同时Closure::bind()方法的第2个参数需要为null,因为 静态属性不需要实例,第3个参数可以是类字符串,实例,static.

相关文章:

yjk只算弹性的不计算弹塑性_基于ANSYS Workbench的表面裂纹计算

一、写在前面本教程使用ANSYS Workbench17.0 进行试件表面裂纹的分析,求应力强度因子。需要提前说明的是,本案例没有工程背景,仅为说明裂纹相的计算方法,因此参数取值比较随意,大量设置都采用了默认值。对于实际工程&a…

《需求分析与系统设计》读书笔记1

这个月开始对《需求分析与系统设计》的阅读,在读这本书之前我先看了看网上对这本书的书评,了解到这本书论述了需求分析和系统设计的迭代增量式过程,并讨论了软件生命周期的其他阶段(包括实现、测试和变化管理)。本书提…

两个主键怎么设置tsql_索引该怎么创建?

1.2、索引 BTree 结构的特性:①、BTree 只有叶子节点会存储真实的数据,非叶子节点只会存储索引字段值;②、BTree的叶子节点之间使用 双向链表 链接,所以更加适合范围查询和排序;2、索引的类型:在平时创建的…

数据库连接池,实现及分析

在我们日常对数据库操作时存在一个问题,要为每次数据操作请求建立一个数据库连接。而每次建立连接都需要花费很多开销,如加载驱动类、注册驱动、获取连接,这样如果在短时间内连接多次,就 会耗费多余的时间(加载驱动注册驱动)*n次&…

BZOJ 1176: [Balkan2007]Mokia( CDQ分治 + 树状数组 )

考虑cdq分治, 对于[l, r)递归[l, m), [m, r); 然后计算[l, m)的操作对[m, r)中询问的影响就可以了. 具体就是差分答案排序离散化然后树状数组维护.操作数为M的话时间复杂度大概是O(M(logM)^2)-----------------------------------------------------------------------#include…

iOS开发之绝对布局和相对布局(屏幕适配)

在IOS的UI设计中也有绝对定位和相对定位,和我们的web前端的绝对定位和相对定位有所不同但又有相似之处。下面会结合两个小demo来学习一下我们IOS开发中UI的绝对定位和相对定位。在前面的博客中所用到的UI事例用的全是绝对定位,用我们Storyboard拖拽出来的…

设计模式5-抽象工厂模式

package DesignPattern;public class AbstractFactory {public static class Dough{}public static class Sauce{}public static class Veggies{}public static class Cheese{}public static class Pepperoni{}public static class Clams{}//披萨public static abstract class …

wp打印输出日志

System.Diagnostics.Debug.WriteLine(String); 转载于:https://www.cnblogs.com/songtzu/archive/2012/07/26/2609678.html

Element-ui表格选中回显

先瞄一下&#xff0c;是不是你要的效果 然后&#xff0c;废话不多说&#xff0c;直接上代码啦 1 <template>2 <div class>3 <div class"projectData">4 <el-table :data"tableData2" ref"multipleTable" :show…

iOS开发者帐号申请指南

如果你是一个开发团队&#xff0c;在你打算掏腰包购买iOS开发者授权之前&#xff0c;最好先问一下你的同事&#xff0c;是否已经有人获得了开发许可&#xff0c;因为一个开发许可一年内最多可以授权给111个设备来开发测试。如果你没有授权许可可以借用&#xff0c;或者你打算最…

Redis的KEYS命令引起宕机事件

摘要&#xff1a; 使用 Redis 的开发者必看&#xff0c;吸取教训啊&#xff01; 原文&#xff1a;Redis 的 KEYS 命令引起 RDS 数据库雪崩&#xff0c;RDS 发生两次宕机&#xff0c;造成几百万的资金损失作者&#xff1a;陈浩翔Fundebug经授权转载&#xff0c;版权归原作者所有…

GridView的编辑,更新,取消,删除等功能演示

GridView的编辑,更新,取消,删除等功能演示 这是一个GridView应用的视频&#xff0c;内容很透彻的讲解了GridView的很多实用的技巧。 下载地址&#xff1a;http://download.cnblogs.com/insus/ASPDOTNET/GridViewEditUpdateCancelDelete.rar posted on 2015-12-15 09:20 代码养家…

mac 使用homebrew 安装mysql

1. 安装homebrew ruby -e "$(curl -fsSL https://raw.github.com/mxcl/homebrew/go)" brew update 2.安装mysql brew install mysql 3.设置 MySQL 用户以及数据存放地址&#xff0c;下载的mysql的mysql_install_db文件中的路径有错误 需要重新设置一下文件路径&…

触控(Touch) 、 布局(Layout)

1 使用触控实现一个简易的画板 1.1 问题 触控&#xff08;Touch&#xff09;是一个UITouch类型的对象&#xff0c;当用户触摸了屏幕上的视图时自动被创建&#xff0c;通常使用触控实现绘图、涂鸦、手写等功能。本案例使用触控实现一个简易的画板&#xff0c;可以在画板上勾画出…

fail-fast和fail-safe的介绍和区别

2019独角兽企业重金招聘Python工程师标准>>> fail-fast和fail-safe 前言 前段时间公司招的实习生在使用迭代器遍历的时候,对集合内容进行了修改,从而抛出ConcurrentModificationException. 然后给他讲解之余也整理了这一篇文章. fail-fast ( 快速失败 ) 在使用迭代器…

hdu 4311 Meeting point-1

http://acm.hdu.edu.cn/showproblem.php?pid4311 思维呀 亲 你想到就可以做出来 想不到就做不出了 什么都不说了 上代码 不知道为什么 在hdu 上 long long 和 int 相乘就让我错 #include<iostream> #include<cstdio> #include<algorithm> #include<c…

Spring Boot 整合Pagehelper(为什么PageHelper分页不生效)

引入包https://mvnrepository.com/artifact/com.github.pagehelper/pagehelper-spring-boot-starter/1.2.10 <!--分页--><!-- https://mvnrepository.com/artifact/com.github.pagehelper/pagehelper-spring-boot-starter --><dependency><groupId>com…

关于javascript的keycode

javascript event对象的具体功能是 event对象只在事件发生的过程中才有效&#xff08;比如鼠标点击&#xff0c;键盘按下等&#xff09;。event对象用以表示事件的状态&#xff0c;例如触发event对象的元素&#xff08;event.srcElement&#xff09;、鼠标的位置&#xff08;ev…

SQL-54 查找排除当前最大、最小salary之后的员工的平均工资avg_salary。

题目描述 查找排除当前最大、最小salary之后的员工的平均工资avg_salary。CREATE TABLE salaries ( emp_no int(11) NOT NULL,salary int(11) NOT NULL,from_date date NOT NULL,to_date date NOT NULL,PRIMARY KEY (emp_no,from_date));输出格式:avg_salary69462.5555555556SQ…

JqGridView 1.0.0.0发布

前几个月&#xff0c;客户要求显示列表做到列锁定表头锁定列组合,但从Extjs到Jquery EasyUi&#xff0c;从Jquery Grid到Telerik等等组件&#xff0c;发现无一符合条件&#xff0c;要么只能用列锁定&#xff0c;要么只能用列组合&#xff0c;当两者结合就不行了。于是只好开始自…

Struts2--ActionContext及CleanUP Filter

1. ActionContext ActionContext是被存放在当前线程中的&#xff0c;获取ActionContext也是从ThreadLocal中获取的。所以在执行拦截器、 action和result的过程中&#xff0c;由于他们都是在一个线程中按照顺序执行的&#xff0c;所以可以可以在任意时候在ThreadLocal中获取 Act…

HTML5跳转页面并传值以及localStorage的用法

1、首先&#xff0c;你得在那个页面把数据存入localStorage中吧。这个是必须的&#xff01; localStorage.setItem("user",JSON.stringify(data.allUser)); 用localStorage的setItem方法&#xff0c;这个方法看名字都知道得差不多了吧。。。setItem把数据存入localSt…

冒泡排序_python实现冒泡排序

冒泡排序是比较经典的面试题&#xff0c; 它重复地走访过要排序的元素列&#xff0c;依次比较两个相邻的元素&#xff0c;如果他们的顺序(如从大到小、首字母从A到Z)错误就把他们交换过来。走访元素的工作是重复地进行直到没有相邻元素需要交换&#xff0c;也就是说该元素列已经…

30分钟内让你明白正则表达式是什么,并对它有一些基本的了解(二)

测试正则表达式 如果你不觉得正则表达式很难读写的话&#xff0c;要么你是一个搞笑的天才&#xff0c;要么&#xff0c;你不是地球人。正则表达式的语法很令人头疼&#xff0c;即使对经常使用它的人来说也是如此。由于难于读写&#xff0c;容易出错&#xff0c;所以找一种工具对…

(区间dp 或 记忆化搜素 )Brackets -- POJ -- 2955

http://poj.org/problem?id2955 Description We give the following inductive definition of a “regular brackets” sequence: the empty sequence is a regular brackets sequence,if s is a regular brackets sequence, then (s) and [s] are regular brackets sequences…

[初级]深入理解乐观锁与悲观锁

2019独角兽企业重金招聘Python工程师标准>>> 在数据库的锁机制中介绍过&#xff0c;数据库管理系统&#xff08;DBMS&#xff09;中的并发控制的任务是确保在多个事务同时存取数据库中同一数据时不破坏事务的隔离性和统一性以及数据库的统一性。 乐观并发控制(乐观锁…

Umbra 3:次世代的遮挡裁剪

原文链接&#xff1a;http://www.gamasutra.com/view/feature/164660/sponsored_feature_next_generation_.php?print1 来自 Umbra Software [在这个主办方特辑中&#xff0c;Umbra Software讨论了当前使用的大量裁剪遮挡方法的优缺点&#xff0c;并解释了它自己的自动化遮挡…

在64位机上PLSQL连oracle11g问题:SQL*Net not properly installed和ORA-12154:TNS:无法处理服务名...

今天有同事在给客户安装我们的系统时&#xff0c;出现了问题。 背景&#xff1a;同事安装如下&#xff1a; 服务器是小机&#xff0c;在小机上做的虚拟机。WIN&#xff12;&#xff10;&#xff10;&#xff13;操作系统&#xff0c;装的是&#xff16;&#xff14;位的。 数据…

ios 应用和电脑共享文件夹_堪比AirDrop,苹果 iPhone与Windows电脑互传文件的三种方式...

如果你是苹果全家桶用户&#xff0c;一定会对 「AirDrop(隔空投送)」 功能赞誉有加&#xff0c;使用 AirDrop 可以在 iPhone 与 MacBook、iPad 等设备之间快速传递照片、视频或文件。遗憾的是&#xff0c;「AirDrop 仅限苹果设备之间使用」&#xff0c;而很多小伙伴应该和小兽一…

Swift----函数 、 闭包 、 枚举 、 类和结构体 、 属性

1 数组排序 1.1 问题 本案例实现一个整型数组排序的函数&#xff0c;数组排序的规则由传递的规则函数决定。 1.2 方案 首先定义一个整型数组排序函数sortInts&#xff0c;该函数有一个整型数组类型的参数&#xff0c;该参数必须是输入输出参数inout&#xff0c;否则并不能修改数…