考虑以下:
protocol ViewControllable: class {
typealias VM: ViewModellable
var vm: VM! { get }
func bind()
}
extension ViewControllable {
var vm: VM! {
didSet {
bind()
}
}
}
Run Code Online (Sandbox Code Playgroud)
我正在尝试观察vm属性并bind在注入时调用它.但这不会编译错误说:
扩展名可能不包含存储的属性
这是有道理的,因为协议不能强制执行属性stored或computed.
这可能在没有介绍的情况下完成class inheritance吗?
换句话说,我可以观察协议扩展内属性的变化吗?
我已经看到有两种方法(其中一个比另一个更小)的声明implicit为类型类模式在Scala中.
implicit val instance1 = new Typeclass { def do = ??? }
implicit object instance2 extends Typeclass { def do = ??? }
Run Code Online (Sandbox Code Playgroud)
他们有什么不同?在某些时候,人们应该更喜欢一个吗?我找到implicit val了比implicit object我更常用的东西,而且我还没有找到很多资源implicit object.
我知道static关键字用于声明类型变量/在方法struct,enum等等.
但今天我发现它也可以在class实体中使用.
class foo {
static func hi() {
println("hi")
}
class func hello() {
println("hello")
}
}
Run Code Online (Sandbox Code Playgroud)
什么是static关键字的使用class实体?
谢谢!
编辑:我指的是Swift 1.2,如果这有任何区别的话
我知道swift不允许在扩展中声明存储的属性.同样地,也禁止延迟加载的属性.我知道计算属性是另一种选择,但我所拥有的任务应该只执行一次.
是否有任何黑客/替代/被忽视的方式来模仿延伸中的懒惰变量?
谢谢!
我目前正在遵循Scala中的函数编程
这是applyin 的伪实现List[A]
def apply[A](as: A*): List[A] =
if (as.isEmpty) Nil
else ::(as.head, apply(as.tail: _*))
Run Code Online (Sandbox Code Playgroud)
如果我忽略: _*的as.tail: _*,斯卡拉抱怨的类型不匹配,这是有道理的,因为as.tail是Seq[A]在这里.
但这_*到底做了什么?
编辑::
正确的术语是序列通配符
考虑以下:
trait Platform {
type Arch <: Architecture
def parseArch(str: String): Option[Arch]
}
object Platform {
def parse(str: String): Option[Platform] = ???
}
trait Architecture
def main() {
def exec(p: Platform)(a: p.Arch) = ???
Platform.parse("ios")
.flatMap(p => p.parseArch("arm64").map(a => (p, a)))
.flatMap { case (p, a) => exec(p)(a) } // <----- This fails to compile
}
Run Code Online (Sandbox Code Playgroud)
exec(p)(a) 无法编译并显示错误消息:
错误:(17,40)类型不匹配;
实测值:a.type(与下面的A型$ A2.this.Platform#拱)
需要:p.Arch .flatMap {情况下(P,A)=> EXEC(P)的(a)}
从错误消息来看,似乎scalac无法保留依赖于的值(p)Arch,因此它选择键入投影(尽管我不太确定是什么A$A2.this)的意思.
为了它的价值,用以下代码替换最后一行将编译:
.flatMap(p => exec(p)(p.parseArch("arm64").get))
Run Code Online (Sandbox Code Playgroud)
这是scala编译器的限制还是我在这里遗漏了一些东西?
也许这个问题需要一些背景知识.
我一直在使用Core Data处理我的持久层,发现Core Data不是线程安全的,因此只需要NSManagedObjectContext限制在每个线程中.
所以我的方法是创建自定义后台线程NSManagedObjectContext,执行抓取,保存等,同时还创建主线程NSManagedObjectContext,用于NSManagedObject从获取中获取NSManagedObjectId并将其传递给调用方法.
默认情况下,Xcode的生成与核心数据模板的代码中使用lazy var的所有NSManagedObjectContext,NSManagedObjectModel等等.
所以我的问题是,是否
使用lazy var实例化方法进行创建NSManagedObjectContext,前提是lazy var为每个尝试访问的线程启动一个对象(不是线程安全的?)
要么
NSManagedObjectContext在每个线程中声明单独的变量,并使所有与线程相关的方法引用两个不同的方法,NSManagedObjectContext这些方法lazy var是线程安全的(?),并且在访问它时只创建一次,而不管线程如何.
先感谢您!
编辑:任何正在努力解决Core Data并发问题的人,本文列出了一个非常好的设计模式,正如Aaron在下面的评论中所指出的那样!
考虑以下:
protocol SomeProtocol {
typealias F: Foo
typealias FB: FooBar where FB.Foo == F
}
Run Code Online (Sandbox Code Playgroud)
但这不编译,因为我们不能像这样放入where子句typealias.
我必须在这里遗漏一些东西,因为这可以很容易地做到type parameterization这样:
struct SomeStruct<F: Foo, FB: FooBar where FB.Foo == F> {}
Run Code Online (Sandbox Code Playgroud)
该where条款相当于associated type什么?
考虑以下:
protocol Foo {
typealias A
func hello() -> A
}
protocol FooBar: Foo {
func hi() -> A
}
extension FooBar {
func hello() -> A {
return hi()
}
}
class FooBarClass: FooBar {
typealias A = String
func hi() -> String {
return "hello world"
}
}
Run Code Online (Sandbox Code Playgroud)
这段代码编译.但是如果我注释掉关联类型的显式定义typealias A = String,那么由于某种原因,swiftc无法推断出类型.
我感觉这与两个共享相同关联类型但没有直接断言的协议有关,例如,类型参数化(可能关联类型不够强大/不够成熟?),这使得类型推断模糊不清.
我不确定这是否是该语言的错误/不成熟,或者可能,我错过了协议扩展中的一些细微差别,这恰恰导致了这种行为.
有人可以对此有所了解吗?