我可以创建一个迭代器来创建前缀:
2018-11-16 15:08:01.523 INFO 8604 --- [ost-startStop-1]
c.n.c.sources.URLConfigurationSource : To enable URLs as dynamic
configuration sources, define System property
archaius.configurationSource.additionalUrls or make config.properties
available on classpath.
2018-11-16 15:08:01.555 INFO 8604 --- [ost-startStop-1]
c.netflix.config.DynamicPropertyFactory : DynamicPropertyFactory is
initialized with configuration sources:
com.netflix.config.ConcurrentCompositeConfiguration@ef4443e
2018-11-16 15:08:01.977 ERROR 8604 --- [ost-startStop-1]
o.s.b.c.embedded.tomcat.TomcatStarter : Error starting Tomcat context.
Exception: org.springframework.beans.factory.UnsatisfiedDependencyException.
Message: Error creating bean with name'org.springframework.cloud.netflix.zuul.ZuulConfiguration$ZuulFilterConfigur
ation': Unsatisfied dependency expressed through field 'filters'; nested
exception is org.springframework.beans.factory.BeanCreationException: Error
creating bean with name 'preFilter': Injection of autowired dependencies
failed; nested exception is java.lang.IllegalArgumentException: Could not
resolve placeholder 'zuul.prefix' in value "${zuul.prefix}"
现在我想通过以下方法实现与其他类型的相同:
1)将类型编码为整数
2)使用相同的前缀功能
3)解码回原始类型
[我知道可能还有其他方法可以实现这一目标,但是出于各种原因,我也想遵循这一思路,并且还想了解更多。]
所以我需要:
extension Array where Element == Int {
func prefixesInt() -> AnyIterator<[Element]> {
var length = 0
return AnyIterator {
guard length < self.count else { return nil }
length += 1
return Array(self.prefix(length))
}
}
}
for prefix in [1,10,5].prefixesInt() {
print(prefix) // Prints: [1] then [1, 10] then [1, 10, 5]
}
我现在可以做我想做的事
extension Array where Element: Equatable {
func encode() -> [Int] {
return map { self.firstIndex(of: $0)! }
}
}
print(["A", "B", "A", "C"].encode()) // Prints: [0, 1, 0, 3]
extension Array where Element == Int {
func decode<Output>(_ original: [Output]) -> [Output] {
return map { original[$0] }
}
}
print([2,3,0].decode(["P", "Q", "R", "S"])) // Prints: ["R", "S", "P"]
我现在想更进一步,将转换(在本例中为前缀)转换为参数,而我的尝试是:
extension Array where Element: Equatable {
func prefixes() -> LazyMapSequence<AnyIterator<[Int]>, [Element]> {
return encode().prefixesInt().lazy.map { $0.decode(self) }
}
}
for prefix in ["H","A","T"].prefixes() {
print(prefix)
}
可以编译,但是当我尝试时:
extension Array where Element: Equatable {
func encodeTransformDecode(transform: ([Int]) -> AnyIterator<[Int]> ) -> LazyMapSequence<AnyIterator<[Int]>, [Element]> {
return transform(encode()).lazy.map { $0.decode(self) }
}
}
然后我得到指示的错误
我被困住了。任何帮助表示赞赏。
整个代码:
extension Array where Element: Equatable {
func prefixes2() -> LazyMapSequence<AnyIterator<[Element]>, [Element]> {
return encodeTransformDecode(transform: prefixesInt) //ERROR: 'Array<Element>' is not convertible to 'Array<Int>'
}
}
for prefix in ["A","B","C"].prefixes2() {
print(prefix)
}
答案 0 :(得分:1)
正如我的评论中所指出的,并且您已经在自己的答案中进行了研究,代码中的核心问题是prefixesInt
的类型不正确。实例方法具有以下形式的类型:
(<object type>) -> (<argument types>) -> <return type>
为<object type>
传递的值是函数中绑定到self
的值。因此,类型prefixesInt
为:
([Int]) -> () -> AnyIterator<[Int]>
要修复代码,只需更改prefixes2
:
func prefixes2() -> LazyMapSequence<AnyIterator<[Int]>, [Element]>
{
return encodeTransformDecode(transform: { $0.prefixesInt() } )
}
类型已更改为包括AnyIterator<[Int]>
而不是AnyIterator<[Element]>
,并且传递了闭包{ $0.prefixesInt() }
而不是prefixesInt
(前者将数组作为参数,而编译器将后者(是self.prefixesInt
的简写形式)传递为闭包,并预先绑定当前值为self
– self
为Array<Equatable>
prefixes2
被调用)。
HTH
要查看与您生成的代码之间的联系,请考虑:
<value>.method(<args>)
只是以下各项的简写:
<type of value>.method(<value>)(<args>)
在这种情况下意味着:
$0.prefixesInt()
是以下内容的简写:
Array<Int>.prefixesInt($0)()
这是您制作的,但分布在prefixes()
(Array<Int>.prefixesInt
)和encodeTransformDecode
(transform(encode())()
)之间。通过使用速记并传递闭包,无需更改encodeTransformDecode
。
答案 1 :(得分:0)
在@ Carpsen90和@CRD的有用推动下(都感谢!),还有一些人潜入精湛的书《 obj Functional Swift》(没有人脉关系),我找到了解决方案。
实例方法的类型不同于静态方法,如下所示:
extension Int {
static func doubleStatic(_ x: Int) -> Int { return x * 2 }
func doubleInstance() -> Int { return self * 2 }
}
print( type(of: Int.doubleStatic) ) // Prints: (Int) -> Int
print( type(of: Int.doubleInstance) ) // Prints: (Int) -> () -> Int
在问题中,prefixesInt
的类型实际上是:(Array<Int>) -> () -> AnyIterator<[Int]>
。
考虑到这一点,我们可以如下重写encodeTransformDecode
:
extension Array where Element: Equatable {
func encodeTransformDecode(transform: (Array<Int>) -> () -> AnyIterator<[Int]> ) -> LazyMapSequence<AnyIterator<[Int]>, [Element]> {
return transform(encode())().lazy.map { $0.decode(self) }
}
}
第二,在prefixesInt
中使用prefixes2
的类型时,我们需要告诉编译器更多信息,以便:
extension Array where Element: Equatable {
func prefixes2() -> LazyMapSequence<AnyIterator<[Int]>, [Element]> {
return encodeTransformDecode(transform: Array<Int>.prefixesInt)
}
}
,现在按要求:
for prefix in ["A","B","C"].prefixes2() {
print(prefix)
}
给予我们
["A"]
["A", "B"]
["A", "B", "C"]
现在很容易地,我们可以很简洁地扩展其他功能:
extension Array where Element == Int {
func suffixesInt() -> AnyIterator<[Element]> {
var length = 0
return AnyIterator {
guard length < self.count else { return nil }
length += 1
return Array(self.suffix(length))
}
}
}
extension Array where Element: Equatable {
func suffixes2() -> LazyMapSequence<AnyIterator<[Int]>, [Element]> {
return encodeTransformDecode(transform: Array<Int>.suffixesInt)
}
}
for suffix in ["A","B","C"].suffixes2() {
print(suffix)
}