我知道&符号有点操作,但有时候我会在变量名称前面看到它.是什么把一个&
在前面的变量做?
我想有一个指针作为类的参数.但是当我尝试编写init时,我遇到了这个错误:Cannot pass immutable value of type 'AnyObject?' as inout argument
class MyClass {
var valuePointer: UnsafeMutablePointer<AnyObject?>
init(value: inout AnyObject?) {
self.valuePointer = &value
}
}
Run Code Online (Sandbox Code Playgroud)
我想创建一些MyClass的实例,它们都可以引用相同的"值".然后,当我在这个类中编辑这个值时,它会在其他地方改变.
这是我第一次使用Swift中的指针.我想我做错了......
问题:基于以下信息和讨论:inout
参数是通过引用传递还是通过拷入拷出?
基于以下SO线程,通过引用传递inout
关键字标记的函数参数:
我们注意到最顶层的两个线程是 Swift 2.0 之前的;我在 SO 上找不到关于该主题的任何更新的讨论(除了有点相关的第三个线程链接)。
但是,根据 Apple 的文档(据我所知),由inout
关键字标记的函数参数是通过copy-in copy-out(或按值调用结果)传递的
传入传出参数如下:
当函数被调用时,参数的值被复制。在函数体中,副本被修改。当函数返回时,副本的值被分配给原始参数。此行为称为拷入拷出或按值结果调用。...
... 您可以通过将 inout 关键字放在其参数定义的开头来编写输入输出参数。一个输入输出参数有一个传入函数的值,被函数修改,然后传回函数外来替换原来的值。...
现在我自己的例子试图调查这个:
struct MyStruct {
private var myInt: Int
mutating func increaseMyInt() {
myInt++
}
func …
Run Code Online (Sandbox Code Playgroud) 我觉得在以下代码中使用swift inout参数有点丢失:
var shouldContinue: Bool = true
func doSomeWork1(shouldContinue: inout Bool)
{
while shouldContinue
{
// ERROR: the compiler wants: doSomeWork2(shouldContinue: &shouldContinue)
doSomeWork2(shouldContinue: shouldContinue)
}
}
func doSomeWork2(shouldContinue: inout Bool)
{
while shouldContinue
{
}
}
Run Code Online (Sandbox Code Playgroud)
为什么编译器需要doSomeWork2(shouldContinue: &shouldContinue)
而不是the compiler wants: doSomeWork2(shouldContinue: shouldContinue)
?是不是shouldContinue
doSomeWork1()范围内的指针???
我在苹果网站上阅读了快速文档.有一个函数swapTwoValues,它可以交换两个给定的值
func swapTwoValues1<T>(_ a: inout T, _ b: inout T) {
let temporaryA = a
a = b
b = temporaryA
}
Run Code Online (Sandbox Code Playgroud)
现在我想写类似的功能,但不是使用T泛型类型,我想使用Any
func swapTwoValues2(_ a: inout Any, _ b: inout Any) {
let temporaryA = a
a = b
b = temporaryA
}
Run Code Online (Sandbox Code Playgroud)
我写这个函数
var a = 5
var b = 9
swapTwoValues1(&a, &b)
swapTwoValues2(&a, &b)
Run Code Online (Sandbox Code Playgroud)
我有两个问题.
1)为什么编译器为第二个函数提供此错误(不能将不可变值作为inout参数传递:从'Int'到'Any'的隐式转换需要临时的)
2)Generic类型和Any之间有什么区别
我尝试重新分配引用NSLayoutConstraint.
class ViewController: UIViewController {
@IBOutlet weak var myConstraint: NSLayoutConstraint!
override func viewDidLoad() {
super.viewDidLoad()
exchangeConstraint(&myConstraint)
}
}
extension UIViewController {
func exchangeConstraint(_ constraint: inout NSLayoutConstraint) {
let spacing = constraint.constant
view.removeConstraint(constraint)
constraint = view.topAnchor.constraint(equalTo: anotherView.topAnchor, constant: spacing)
view.addConstraint(constraint)
}
}
Run Code Online (Sandbox Code Playgroud)
但在这里它给了我错误:
exchangeConstraint(&myConstraint)
-------------------^
Cannot pass immutable value of type 'NSLayoutConstraint' as inout argument
Run Code Online (Sandbox Code Playgroud)
我不明白的是它为什么说不可变值,而约束被声明为变量,而不是常量.
在Swift 2中,可以执行以下操作:
class SomeType {
static let singletonInstance = SomeType()
func someFunction(var mutableParameter: SomeType = SomeType.singletonInstance) {
...
}
}
Run Code Online (Sandbox Code Playgroud)
但是在Swift 3中,var
关键字将被移除,以支持函数参数inout
.我无法使用inout
关键字获得与上述相同的结果.
class SomeType {
static let singletonInstance = SomeType()
func someFunction(inout mutableParameter: SomeType = SomeType.singletonInstance) {
...
}
}
Run Code Online (Sandbox Code Playgroud)
相反,我收到一个错误"类型'SomeType'的默认参数值无法转换为类型'inout SomeType'"
我的问题是,是否可以使用inout
默认值?
更新数组中项目的最简单/正确的方法是什么?我希望调用者也拥有更新的数组。所以:
static func updateItem(updatedItem: Item, inout items: [Item]) -> Bool {
var item = items.filter{ $0.id == updatedItem.id }.first
if item != nil {
item = updatedItem
return true
}
return false
}
Run Code Online (Sandbox Code Playgroud)
我希望调用者拥有更新的项目(带有更新的项目)。我认为上面代码的问题在于它只更新了局部变量 item。实际更新 items 数组中的相关项的最佳方法是什么?
如果将指针传递给只读函数,则该指针是 IN 参数。
如果一个指针被传递给一个只读函数,但是这个函数创建了一个指针的副本,以便在只读操作的模块相关函数中访问它,这个指针仍然是 IN。
如果函数仍然使用指针作为只读,但其他模块相关函数使用指针进行写操作,那么指针是什么?一个 IN 参数,但没有 const?输入/输出参数?
我的意思的例子:
class SteeringWheel {
public: float rotation;
public: SteeringWheel(void) {
this->rotation = 0.f;
}
};
class Car {
private: SteeringWheel *steeringWheel;
public:
/**
* @param[?] steeringWheel Is the steering wheel in or in/out?
*/
Car (SteeringWheel *steeringWheel) {
this->steeringWheel = steeringWheel;
}
/**
* @param[in] degree Steering amount in degrees.
*/
void steer(float degree)
{
this->steeringWheel->rotation += degree;
}
};
int main(int argc, char **argv)
{
SteeringWheel steeringWheel();
/* car() uses …
Run Code Online (Sandbox Code Playgroud) 根据Swift文档,mutation和inout关键字均用于从函数内部修改值类型。“变异”和“输入”之间是否有任何区别,以及在任何需要使用它们之一的特殊情况下,有什么区别。