【发布时间】:2019-12-15 10:42:22
【问题描述】:
如何用init(arrayLiteral:)初始化方法创建IndexPath对象?
我尝试:
let ip = IndexPath(arrayLiteral: [0,0])
但收到错误消息
无法将“[Int]”类型的值转换为预期的参数类型 'IndexPath.Element'(又名'Int')
【问题讨论】:
如何用init(arrayLiteral:)初始化方法创建IndexPath对象?
我尝试:
let ip = IndexPath(arrayLiteral: [0,0])
但收到错误消息
无法将“[Int]”类型的值转换为预期的参数类型 'IndexPath.Element'(又名'Int')
【问题讨论】:
IndexPath(arrayLiteral:) 初始值设定项是ExpressibleByArrayLiteral 协议的一部分,其用途——顾名思义——从数组字面量初始化索引路径:
数组字面量是表示值列表的一种简单方式。只需用方括号将值、实例或文字的逗号分隔列表括起来即可创建数组文字。
例子:
let ip: IndexPath = [0, 0]
let ip = [0, 0] as IndexPath
编译器自动将其转换为对IndexPath(arrayLiteral:)的调用,您可以通过检查中间语言来验证
swiftc -emit-sil main.swift
// ...
%19 = function_ref @$s10Foundation9IndexPathV12arrayLiteralACSid_tcfC : $@convention(method) (@owned Array<Int>, @thin IndexPath.Type) -> @out IndexPath // user: %20
%20 = apply %19(%3, %8, %4) : $@convention(method) (@owned Array<Int>, @thin IndexPath.Type) -> @out IndexPath
// ...
一般情况下,init(xxxLiteral:) 方法需要使类型符合ExpressibleByXXXLiteral 协议并由编译器使用,但通常不直接调用。
交替使用
let ip = IndexPath(indexes: [0, 0])
这两种方法都可以用于任意长度的索引路径。
对于表和集合视图,需要精确长度为 2 的索引路径,并且可以更富有表现力地创建这些路径
let ip = IndexPath(row: 0, section: 0) // table view
let ip = IndexPath(item: 0, section: 0) // collection view
但结果是一样的。
【讨论】:
let ip = IndexPath(indexes: [0, 1, 2]); print(ip) 不会崩溃。索引路径不限于与表/集合视图一起使用。
print(ip.row)) 或部分 (`print(ip.section)`) 时,它会崩溃。再一次,你的答案是正确的!
init(arrayLiteral:) 方法由 编译器 使用,但并不意味着直接调用。
它不需要数组,而是IndexPath.Element 类型的“序列”。
let ip = IndexPath(arrayLiteral: 0, 1) // Array [0,1]
// Excerpt from playground: ""ip 0 row 1"\n"
debugPrint("ip \(ip.section) row \(ip.item)")
【讨论】: