我来自Java世界,我想知道在编译代码时除了缺少错误外,Python中的动态类型有什么好处?
你喜欢Python的打字吗?你有一个例子,它在一个大项目中有所帮助吗?是不是有点容易出错?
说实话,我不知道怎么说这个问题所以请原谅我,如果实际问题不是你所期望的基于标题.C#是我编写过的第一个静态类型的语言,到目前为止,它对我来说是一个绝对头疼的问题.我很确定我对于如何以静态类型的方式设计系统的核心思想没有很好的处理.
这是我想要做的一个粗略的想法.假设我有一个类的层次结构,如下所示:
abstract class DataMold<T>
{
public abstract T Result { get; }
}
class TextMold : DataMold<string>
{
public string Result => "ABC";
}
class NumberMold : DataMold<int>
{
public int Result => 123
}
Run Code Online (Sandbox Code Playgroud)
现在假设我想要列出项目列表,其中项目可以是任何类型的模具,我可以Result在foreach循环中获取每个项目的属性,如下所示:
List<DataMold<T>> molds = new List<DataMold<T>>();
molds.Add(new TextMold());
molds.Add(new NumberMold());
foreach (DataMold<T> mold in molds)
Console.WriteLine(mold.Result);
Run Code Online (Sandbox Code Playgroud)
正如您可能已经知道的那样,这不起作用.从我在搜索中看到的内容来看,它与我无法将List声明为类型这一事实有关DataMold<T>.这样做的正确方法是什么?
例如在python3中定义函数的参数时,使用list和List有什么区别?例如,有什么区别
def do_something(vars: list):
Run Code Online (Sandbox Code Playgroud)
和
def do_something(vars: List):
Run Code Online (Sandbox Code Playgroud)
该文件说:
类打字。列表(列表,MutableSequence[T])
列表的通用版本。用于注释返回类型。
但我不完全确定以上是什么意思。
我有类似的问题:dict vs dict、set vs set等。
我正在使用vb.net中的泛型类.
并且似乎扩展方法不能在没有指定类型的情况下应用于泛型类.
我有这个通用类
Public Class MyGeneric(Of T)
'Methods and properties go here
'
'
End Class
Run Code Online (Sandbox Code Playgroud)
还行吧
<Extension()> _
Public Sub DoSomething(ByVal myGenericDoubleObj As MyGen(Of Double))
End Sub
Run Code Online (Sandbox Code Playgroud)
这不行(IDE给我的错误T未定义.)
<Extension()> _
Public Sub DoSomethingGeneric(ByVal myGenericObj As MyGen(Of T))
End Sub
Run Code Online (Sandbox Code Playgroud)
这与.Net的静态检查有关.
对我说"你可能尝试用T型做的事可能不兼容,我不会允许你这样做."
PS我作为通用类所带来的所有痛苦来自另一个库,并在许多不同的地方使用.我很遗憾在继承的泛型类中继承和添加此方法.
我正在阅读保罗格雷厄姆的"百年语言"一文.
http://www.paulgraham.com/hundred.html
在那里,他声称静态输入"排除[s]真正的宏".
例如,类型似乎是取之不尽的研究论文来源,尽管静态类型似乎排除了真正的宏 - 否则,在我看来,没有语言值得使用.
这是怎么回事?论文在哪里?我尝试在Google上搜索但没有成功.
OOP原则(如果有的话)在动态类型环境中不适用或应用不同,而不是静态类型环境(例如Ruby vs C#)?这不是对静态与动态辩论的呼吁,而是我想看看是否存在适用于一方而非另一方适用于该范围的任何一方的公认原则,或者采用不同的方式.在"静态类型"OOP文献中,诸如"喜欢组合到继承"的短语是众所周知的.它们是否适用于动态方面?
例如,在动态类型环境中,似乎耦合的粒度不会超过方法的级别.换句话说,任何给定的函数调用只将调用者耦合到任何类可能满足的特定接口- 或者换句话说,任何像那个特定的鸭子那样嘎嘎叫的东西.
另一方面,在Java中,耦合的粒度可以与包一样高.一个特定的方法调用不仅与另一个类/接口建立契约,而且还将它耦合到该类/接口的package/jar/assembly中.
像这样的差异会产生不同的原则和模式吗?如果是这样,这些差异是否明确表达了?Ruby Pickaxe书中有一节向这个方向发展(Duck Typing/Classes Are Types),但我想知道是否还有其他内容.我知道Ruby中的设计模式,但还没有读过它.
编辑 - 有人认为Liskov在动态环境中并不像在静态环境中那样应用它,但我不禁想到它确实如此.一方面,没有与全班同学的高级合同.但是,不是所有对任何特定类别的调用构成一个隐含的契约,需要像Liskov所规定的那样由子类来满足吗?考虑以下."做一些酒吧"的电话会创建一个需要由子课程来处理的合同.这不是"将专门对象视为基类吗?"的情况:
class Bartender
def initialize(bar)
@bar = bar
end
def do_some_bar_stuff
@bar.open
@bar.tend
@bar.close
end
end
class Bar
def open
# open the doors, turn on the lights
end
def tend
# tend the bar
end
def close
#clean the bathrooms
end
end
class BoringSportsBar < Bar
def open
# turn on Golden Tee, fire …Run Code Online (Sandbox Code Playgroud) oop design-patterns static-typing dynamic-typing static-language
好的,首先要解决这个问题:我已经阅读了以下答案:
但我真的不明白它的答案.
在像Python这样的语言中,表达式为:
x = a + b
Run Code Online (Sandbox Code Playgroud)
无法真正编译,因为"编译器"不可能知道a和b的类型(因为类型只在运行时知道),因此如何添加它们.
这就是使Python这样的语言在没有类型声明的情况下无法编译的原因,对吗?通过声明,编译器知道例如a和b是整数,因此知道如何添加它们,并将其转换为本机代码.
那怎么做:
(setq x 60)
(setq y 40)
(+ x y)
Run Code Online (Sandbox Code Playgroud)
工作?
编译被定义为本机提前编译.
编辑
实际上,这个问题更多的是关于是否可以编译没有类型声明的动态语言,如果是,如何编译?
编辑2
经过大量研究(即狂热的维基百科浏览),我想我理解以下内容:
如果我在上述任何一点上错了,请纠正我.
如果我有这样的事情
const RandomComponent = (props) => (
<div>
<SomeSubComponent id={props.id} />
<AnotherSubComponent type={props.type} />
</div>
)
Run Code Online (Sandbox Code Playgroud)
我将如何用Flow键入注释返回类型,即/* ??? */在下面的代码中应该替换什么?
const RandomComponent = (props: { id: string, vino: number): /* ??? */ => (
<div>
<SomeSubComponent id={props.id} />
<AnotherSubComponent veryImportantNumber={props.vino} />
</div>
)
Run Code Online (Sandbox Code Playgroud)
编辑:这就是Flow文档对无状态功能组件的看法.我可能是盲人,但我看不到有关返回类型的任何内容,只有道具类型.
当我开始使用Lift时,我有点惊讶它使用反射(或似乎),它在静态类型的函数语言中有点出乎意料.我对JSP的经验与此类似.
我对Web开发很新,所以我真的不知道这些工具是如何工作的,但我想知道,
Web开发的哪些方面鼓励使用反射?
是否有任何工具(在静态类型语言中)处理(1)引用模板页面中的代码(2)对象关系映射,以不使用反射的方式?
在 Rust 中,一个明确的类型impl Trait for Object保证了它Object具有这一特性。现在,C++20 概念当然更加笼统一些,因为它们不仅仅与一种类型相关联,而且可能与多种类型相关联。然而,这引出了一个问题:如何确定您实现的某些类型实际上满足某些概念。
现在的概念有点鸭子式,如果你的对象满足了有人试图在一个requires块中用它做的所有事情(它像鸭子一样嘎嘎叫),那么它就会像鸭子一样传递并满足这个概念。但是有没有办法说:“我希望这个分类的类能够通过测试”?
例如,这可能看起来像这样:
class MyClass1 { ... }
class MyClass2 { ... }
template<typename T1, T2>
concept MyConcept = requires(T1 t1, T2 t2) { ... }
static_assert( satisfies<MyConcept, MyClass1, MyClass2>() )
Run Code Online (Sandbox Code Playgroud)
这样的函数是否satisfies存在,如果不存在:如何编写这样的satisfies函数?
如果您将对象传递到某些概念的实现是可选的库(例如,接受可能位于或不位于边界的组件并且仅对位于边界的对象执行某些计算的库),则 Ducktyping 可能还不够。
template <typename GeneralComponent>
void do_something_optionally(GeneralComponent component) {
if constexpr ( satisfies<isBorder, GeneralComponent>() ) {
do_border_calculation(component);
} else {
// don't do border calculation
}
}
do_border_calculation(isBorder …Run Code Online (Sandbox Code Playgroud) static-typing ×10
generics ×2
oop ×2
python ×2
.net ×1
c# ×1
c++ ×1
c++-concepts ×1
c++20 ×1
duck-typing ×1
flowtype ×1
java ×1
javascript ×1
lift ×1
lisp ×1
list ×1
macros ×1
python-3.x ×1
reactjs ×1
reflection ×1
scala ×1
typing ×1
vb.net ×1