考虑以下:
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中的函数编程
这是apply
in 的伪实现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无法推断出类型.
我感觉这与两个共享相同关联类型但没有直接断言的协议有关,例如,类型参数化(可能关联类型不够强大/不够成熟?),这使得类型推断模糊不清.
我不确定这是否是该语言的错误/不成熟,或者可能,我错过了协议扩展中的一些细微差别,这恰恰导致了这种行为.
有人可以对此有所了解吗?