在我看过的每个例子中,扩展类都实现了父类的接口.供参考,以下示例:
interface MyInterface{
public function foo();
public function bar();
}
abstract class MyAbstract implements MyInterface{
public function foo(){ /* stuff */ }
public function bar(){ /* stuff */ }
}
// what i usually see
class MyClass extends MyAbstract implements MyInterface{}
// what i'm curious about
class MyOtherClass extends MyAbstract{}
Run Code Online (Sandbox Code Playgroud)
是否未能在子级中实现接口,这是由父级实现的,被视为不良做法或其他什么?省略孩子的实施是否有任何技术缺陷?
在不支持泛型的语言(PHP)中,有哪些策略可以克服特殊化的参数类型不变性?
注意:我希望我可以说我对类型理论/安全/方差等的理解更完整; 我不是CS专业.
你有一个抽象的类,Consumer你想扩展它.Consumer声明一个consume(Argument $argument)需要定义的抽象方法.应该不是问题.
你的专业Consumer,被称为SpecializedConsumer没有逻辑与业务工作的每一个类型的Argument.相反,它应该接受一个SpecializedArgument(及其子类).我们的方法签名更改为consume(SpecializedArgument $argument).
abstract class Argument { }
class SpecializedArgument extends Argument { }
abstract class Consumer {
abstract public function consume(Argument $argument);
}
class SpecializedConsumer extends Consumer {
public function consume(SpecializedArgument $argument) {
// i dun goofed.
}
}
Run Code Online (Sandbox Code Playgroud)
我们打破Liskov替代原则,并导致类型安全问题.船尾.
好的,所以这不会起作用.然而,鉴于这种情况,有什么模式或策略存在克服类型的安全问题,以及违反LSP,但仍保持的类型的关系SpecializedConsumer来Consumer? …
我已经厌倦了PHP对"短三元"的支持,省略了第二个表达式:
// PHP
$foo = 'hello';
$bar = '';
echo $foo ?: 'world'; // hello
echo $bar ?: 'world'; // world
Run Code Online (Sandbox Code Playgroud)
Javascript是否支持这样的语法?我试过?:导致语法错误.我知道布尔短路,但这对我目前正在做的事情是不可行的; 那是:
// Javascript
var data = {
key: value ?: 'default'
};
Run Code Online (Sandbox Code Playgroud)
有什么建议?(我可以将它包装在一个立即调用的匿名函数中,但这看起来很愚蠢)
在修补这个问题的答案的同时,我发现当从内部调用时,debug_backtrace()不会超出注册的函数register_shutdown_function().
这是中提到此评论为register_shutdown_function()在PHP文档,指出:
您可以从关闭函数内部调用debug_backtrace或debug_print_backtrace,以跟踪致命错误发生的位置.不幸的是,这些功能在关机功能中不起作用.
更详细地解释一下,对这个答案状态的评论:
不行.堆栈取消后会发生关闭功能.没有要转储的堆栈信息.
有没有办法绕过这个,迫使PHP保持堆栈跟踪直到进程完全终止,或者我们应该接受它作为给定由于PHP内部?
虽然我理解$this当在静态上下文中调用方法时该变量不可用,但为了帮助将我的应用程序组件彼此解耦,我认为从实例调用静态方法是有意义的.例如:
class MyExample{
private static $_data = array();
public static function setData($key, $value){
self::$_data[$key] = $value;
}
// other non-static methods, using self::$_data
}
// to decouple, another class or something has been passed an instance of MyExample
// rather than calling MyExample::setData() explicitly
// however, this data is now accessible by other instances
$example->setData('some', 'data');
Run Code Online (Sandbox Code Playgroud)
是否有计划弃用此类功能,或者我是否愿意期待对此的支持?我一起工作error_reporting(-1)以确保一个非常严格的开发环境,并且目前还没有任何问题(PHP 5.3.6)但是我知道反向变得不受支持; 也就是说,静态调用实例方法.
<html>
<?php
$num = 1;
echo $num;
?>
<input type="button"
name="lol"
value="Click to increment"
onclick="Inc()" />
<br>
<script>
function Inc()
{
<?php
$num = 2;
echo $num;
?>
}
</script>
</html>
Run Code Online (Sandbox Code Playgroud)
这是我到目前为止,虽然没有工作,我认为我需要使用ajax或其他东西,但我不知道该怎么做.
谢谢
简单的一点,我只是想知道是否有一种干净而雄辩的方式从一个与给定键不匹配的关联数组中返回所有值?
$array = array('alpha' => 'apple', 'beta' => 'banana', 'gamma' => 'guava');
$alphaAndGamma = arrayExclude($array, array('alpha'));
$onlyBeta = arrayExclude($array, array('alpha', 'gamma'));
function arrayExclude($array, Array $excludeKeys){
foreach($array as $key => $value){
if(!in_array($key, $excludeKeys)){
$return[$key] = $value;
}
}
return $return;
}
Run Code Online (Sandbox Code Playgroud)
这是我(将要)使用的,但是,是否有更清洁的实现,我可能在手册中遗漏了什么?
在JavaScript中,看到自调用函数并不罕见:
var i = (function(x) {
return x;
})(42);
// i == 42
Run Code Online (Sandbox Code Playgroud)
虽然我当然没有比较这些语言,但我认为这样的构造可以翻译成C#,只要提供支持的语言版本:
var i = (delegate(int x) {
return x;
})(42);
Run Code Online (Sandbox Code Playgroud)
要么:
var i = ((x) => {
return x;
})(42);
Run Code Online (Sandbox Code Playgroud)
甚至:
var i = (x => x)(42);
Run Code Online (Sandbox Code Playgroud)
但是,每个版本都有错误:
预期的方法名称
自调用匿名方法是否不受支持(由于显式禁止或类型推断不可能),或者我的尝试中是否存在错误?
我冒昧地猜测,因为没有方法声明(Func<T,T>)可以推断出类型,它无法理清隐含的类型,我打算通过名称调用声明的方法,并且真正搞砸了语法.
勘误表
在此问题充斥之前:
var i = new Func<int, int>(x => x)(42);
Run Code Online (Sandbox Code Playgroud)
我应该说我希望利用类型推断,但我认为由于过于隐蔽而可能无法实现.
所以,澄清一下这个问题; 我们知道我们可以var i = new Func<int, int>(x => x)(42);但是如果没有创建实例,或者转换为Func,这可能吗?
用例
对于那些好奇(或有关)的用例是这样的:
var o …Run Code Online (Sandbox Code Playgroud) c# anonymous-methods anonymous-function self-invoking-function
在处理项目时,我一直在进行一些更改,并浏览现有的框架API文档以获得洞察力.
在仔细阅读Kohana文档时,我注意到任何给定类的getter/setter通常组合在一起:
public function someProperty($value = null){
if(is_null($value){
return $this->_someProperty;
}
$this->_someProperty = $value;
return $this;
}
Run Code Online (Sandbox Code Playgroud)
而不是:
public function setSomeProperty($value){
$this->_someProperty = $value;
return $this;
}
public function getSomeProperty(){
return $this->_someProperty;
}
Run Code Online (Sandbox Code Playgroud)
这样做(前者)是否有任何价值,除了减少给定类的方法数量?我总是在理解方法(一般的功能)应该更能描述一个动作.当他们看到这个时,其他有经验的开发人员是否会畏缩,甚至一点点?
我很惊讶地看到一个流行的框架使用这样的约定(我当然没有使用过Kohana)
我在类之间有一些"setter"方法,为方便起见,我添加了一个可选参数$previous,它通过引用获取参数,并在用新值替换之前用现有值填充它.例如:
public function set_value($key, $value, &$previous = null)
{
$previous = $this->get_value($key);
$this->_values[$key] = $value;
return $this;
}
Run Code Online (Sandbox Code Playgroud)
这很好用; 但是在某些情况下,相应的"getter"方法有点过程密集,无条件运行它是一种浪费.我想我可以测试:
if(null !== $previous)
{
$previous = $this->get_value($key);
}
Run Code Online (Sandbox Code Playgroud)
这不起作用,因为通常作为参数传递的变量$previous先前未在其范围中定义,并且无论如何都默认为null.我遇到的唯一解决方案是:
public function set_value($key, $value, &$previous = null)
{
$args = func_get_args();
if(isset($args[2])
{
$previous = $this->get_value($key);
}
$this->_values[$key] = $value;
return $this;
}
Run Code Online (Sandbox Code Playgroud)
或者,一行:
if(array_key_exists(2, func_get_args()))
{
// ...
}
Run Code Online (Sandbox Code Playgroud)
我不喜欢方法体依赖于参数索引(当它看起来应该是不必要的时候)有没有更清晰的方法来实现我在这里之后的东西?
我试过了:
if(isset($previous)){}
if(!empty($previous)){}
if(null !== $previous){}
Run Code Online (Sandbox Code Playgroud)
都没有工作.
迄今可能的解决方案:
if(func_num_args() == $num_params){}
if(array_key_exists($param_index, func_get_args())){}
// …Run Code Online (Sandbox Code Playgroud) php ×9
javascript ×2
ajax ×1
c# ×1
client-side ×1
covariance ×1
deprecated ×1
function ×1
inheritance ×1
interface ×1
kohana ×1
oop ×1
stack-trace ×1
this ×1
types ×1