在Swift语言中,感叹号是什么意思?


518

Swift编程语言指南包含以下示例:

class Person {
    let name: String
    init(name: String) { self.name = name }
    var apartment: Apartment?
    deinit { println("\(name) is being deinitialized") }
}

class Apartment {
    let number: Int
    init(number: Int) { self.number = number }
    var tenant: Person?
    deinit { println("Apartment #\(number) is being deinitialized") }
}

var john: Person?
var number73: Apartment?

john = Person(name: "John Appleseed")
number73 = Apartment(number: 73)

//From Apple's “The Swift Programming Language” guide (https://developer.apple.com/library/content/documentation/Swift/Conceptual/Swift_Programming_Language/AutomaticReferenceCounting.html)

然后,在将公寓分配给该人时,他们使用感叹号“解开实例”:

john!.apartment = number73

“解开实例”是什么意思?为什么有必要?它与仅执行以下操作有何不同:

john.apartment = number73

我是Swift语言的新手。只是想降低基础知识。


更新:
我遗漏的一大难题(未在答案中直接说明-至少在撰写本文时没有)是在执行以下操作时:

var john: Person?

正如我最初所认为的,这并不意味着“ john是类型Person,可能为零”。我只是误解了PersonPerson?它们是完全独立的类型。一旦我掌握了,所有其他的?!疯狂的,和下面的伟大的答案,做了很多更有意义。

Answers:


530

“解开实例”是什么意思?为什么有必要?

据我所知(这对我来说也是很新的)...

术语“包装”意味着我们应该将一个Optional变量视为礼物,用闪亮的纸包裹,该纸可能(很遗憾!)为空

当“包装”时,Optional变量的值是带有两个可能值的枚举(有点像布尔值)。该枚举描述了变量是否包含值(Some(T)),而不是值(None)。

如果有值,则可以通过“展开”变量(T从中获取Some(T))来获得。

如何john!.apartment = number73不同john.apartment = number73?(改写)

如果您写一个Optional变量的名称(例如text john,不带!),则它是指“包装的”枚举(Some / None),而不是值本身(T)。因此john不是的实例Person,并且没有apartment成员:

john.apartment
// 'Person?' does not have a member named 'apartment'

实际Person值可以通过多种方式展开:

  • “强制展开” :(如果存在,则john!给出该Person值,如果为nil,则给出运行时错误)
  • “可选绑定” :(如果值存在if let p = john { println(p) }println则执行)
  • “可选链接” :(john?.learnAboutSwift()如果值存在,则执行此组合方法)

我猜您选择了其中一种解开包装的方法,具体取决于零情况下应发生的情况以及发生这种情况的可能性。这种语言设计强制显式处理nil案例,我认为这比Obj-C(在这里容易忘记处理nil案例)提高了安全性。

更新

语法中还使用了感叹号,以声明“ Implicitly Unwrapped Optionals”。

在到目前为止的示例中,john变量已声明为var john:Person?,并且是可选的。如果需要该变量的实际值,则必须使用上述三种方法之一将其解包。

如果将其声明为var john:Person!,则该变量将为“隐式展开的可选”(请参阅​​Apple书籍中带有此标题的部分)。访问值时无需解开此类变量,并且john可以在不使用附加语法的情况下使用它。但是苹果的书说:

当变量在以后可能变为nil时,不应使用隐式解包的可选。如果需要在变量的生存期内检查nil值,请始终使用普通的可选类型。

更新2

Mike Ash 的文章“ 有趣的Swift功能 ”为可选类型提供了一些动力。我认为这是很棒的,清晰的文字。

更新3

另一篇关于感叹号隐式展开的可选用法的有用文章:克里斯·亚当森(Chris Adamson)的“ 雨燕与最后一英里 ”。本文解释说,这是Apple用来声明其Objective-C框架使用的类型(可能包含nil)的一种实用措施。将类型声明为可选(使用?)或隐式解包(使用!)是“安全和便利之间的折衷”。在本文给出的示例中,Apple选择将类型声明为隐式解包,从而使调用代码更加方便,但安全性较低。

也许苹果将来可能会梳理它们的框架,消除隐式解开(“可能永远不会为零”)参数的不确定性,并用可选参数(“特别是,(在有希望的情况下,记录在案!)情况可能为零”)或标准-可选(“永不为零”)声明,基于其Objective-C代码的确切行为。


我不确定这个解释。如果您只运行代码而没有!它仍然返回实际值。也许!是为了速度?
理查德·华盛顿

好。因此,文档谈论使用!当您确定可以将其展开时。但是,您可以在没有代码的情况下运行代码(列表的第四个选项-隐式展开),并且无需先检查即可运行代码。您取回该值;如果为nil,则返回nil。但是,如果您确定它不是nil,请使用!......但我仍然看不到您为什么要这样做?
理查德·华盛顿

2
@RichardWashington,您好:我为答案添加了一个更新,希望可以澄清其中的一些问题。
Ashley 2014年

Update 3正是我想要的。在阅读之前,我以为苹果在说谎,因为他们返回了类似NSURLCredential之类的东西!实际上可能是零。
Golden Thumb

感谢您的精彩回答@Ashley。在阅读了此答案和一些Apple的示例快速代码后,在我看来,在安全性和生产率之间的权衡中,通常最好还是更加安全。我发现的一个明显例外是,当Apple对UI元素使用强制展开时,这很有意义,因为首先,UI元素通常在涉及情节提要时是可选的(因为它们没有以编程方式分配值),其次是因为它们几乎是除非其包含的视图控制器为nil,否则永远不要为零,在这种情况下,此讨论无足轻重。
Mihir 2014年

127

我认为这是区别:

var john: Person?

意味着约翰可以为零

john?.apartment = number73

编译器会将这一行解释为:

if john != nil {
    john.apartment = number73
}

john!.apartment = number73

编译器将这一行解释为:

john.apartment = number73

因此,使用!将解开if语句,并使它运行得更快,但是如果john为nil,则会发生运行时错误。

因此,这里包装并不意味着它是内存包装的,而是意味着它是代码包装的,在这种情况下,它是用if语句包装的,并且由于Apple密切关注运行时的性能,因此他们想给您一种方法使您的应用以最佳性能运行。

更新:

4年后回到这个答案,因为我在Stackoverflow中获得了最高的声誉:)我当时误解了解开包装的含义。现在经过4年,我相信这里展开的意思是从原始的紧凑形式扩展代码。这也意味着消除对象周围的模糊性,因为我们不确定它的定义是否为nil。就像上面的阿什利的答案一样,将其视为礼物,其中可能没有任何东西。但是我仍然认为解包是代码解包,而不是像使用枚举那样基于内存的解包。


9
在我的游乐场john.apartment = number73无法编译,您必须指定john?.apartment = number73
Chuck Pinkert

2
@ChuckPinkert是正确的,应该将第四行编辑为john?.apartment = number73,尽管不错的答案!
布鲁斯

john.apartment = number73给出错误:可选类型'Person?'的值 不解包:您的意思是使用'!' 要么 '?'?
蜘蛛侠

4
展开与性能无关。仍然必须在运行时执行“无检查”,唯一的区别是,如果Optional中不存在任何值,则将抛出运行时错误。
madidier

67

TL; DR

在Swift语言中,感叹号是什么意思?

感叹号有效地表示:“我知道此可选选项绝对有价值。请使用它。” 这称为可选值的强制展开:

let possibleString: String? = "An optional string."
print(possibleString!) // requires an exclamation mark to access its value
// prints "An optional string."

let assumedString: String! = "An implicitly unwrapped optional string."
print(assumedString)  // no exclamation mark is needed to access its value
// prints "An implicitly unwrapped optional string."

来源:https : //developer.apple.com/library/content/documentation/Swift/Conceptual/Swift_Programming_Language/TheBasics.html#//apple_ref/doc/uid/TP40014097-CH5-XID_399


11
因为我明白你的回答是伟大的东西是在走了。我不明白的是为什么存在隐式展开的可选。为什么要创建一些定义为隐式展开的可选String而不是常规String类型的东西?此后它们的用法是相同的。我想念什么?
pachun

这似乎不再是真的。在Swift 5的repl中,如果我这样做了let f: String! = "hello",那么print(f)输出将Optional("hello")不是just "hello"
numbermaniac

37

如果john是可选的var(因此声明)

var john: Person?

那么john可能就没有价值了(用ObjC的话来说就是nil值)

感叹号基本上告诉编译器“我知道它有一个值,您不需要测试它”。如果您不想使用它,则可以有条件地对其进行测试:

if let otherPerson = john {
    otherPerson.apartment = number73
}

仅当john具有值时,此内部才会评估。


4
感谢您的答复,我现在明白了感叹号的含义,我仍在努力寻找原因 ... ...您说它告诉编译器“我知道这很有用,您无需测试它”。如果编译器不对其进行测试,它将给我带来什么?如果没有感叹号,编译器是否会引发错误(我还没有可以测试Swift的环境)?是个 !所有可选的var是否需要100%?如果是这样,为什么苹果要烦它,而不是仅仅让它缺少!意味着“我知道这是有价值的,您不需要测试”?
Troy 2014年

“编译器会抛出错误吗?”-不,按预期返回值仍然可以正常工作。我不明白 是个 !只是为了确定速度而已?
理查德·华盛顿

实际上,在稍后的文档中,将使用以下示例来讨论隐式展开的可选对象: “let possibleString: String? = "An optional string." println(possibleString!) // requires an exclamation mark to access its value // prints "An optional string.” 但是,在没有!的情况下,它可以正常工作。这里似乎有些奇怪。
理查德·华盛顿

3
@RichardWashington您有充分的理由感到困惑!文档中的示例遗漏了一些内容,并且具有误导性,因为它们所做的只是使用println。显然,至少在某些情况下不需要拆开可选选项。一种是使用println时。另一个是在使用字符串插值时。那么,也许println和字符串插值在幕后展开了?也许有人对此有更多见识。查看Xcode6 Beta标头定义并没有向我透露有关此魔术的任何信息。
mbeaty

是的,我得到的John?John两种不同的类型。一个是“可选人”类型,另一个是“人”类型。必须先解开“可选人员”,然后才能将其取出。但是正如您所说,这似乎至少在这种情况下会发生,而无需实际执行任何操作。这似乎使!多余的。除非!总是可选的,但是建议采取一些措施来捕获编译时错误。将vars / let分配给特定类型的种类可以很明确,let John: Person = ...但也可以推断出来let John = ...
理查德·华盛顿

27

一些大角度的观点可以添加到其他有用但以细节为中心的答案中:

在Swift中,感叹号出现在以下几种情况中:

  • 强制展开: let name = nameLabel!.text
  • 隐式展开的可选: var logo: UIImageView!
  • 强制铸造: logo.image = thing as! UIImage
  • 未处理的异常: try! NSJSONSerialization.JSONObjectWithData(data, [])

这些中的每一个都是具有不同含义的不同语言构造,但是它们都有三点重要的共同点:

1.感叹号绕过Swift的编译时安全检查。

!在Swift中使用时,您实际上是在说:“嘿,编译器,我知道您认为这里可能会发生错误,但是我知道,总的确定性,它永远不会。”

并非所有有效的代码都适合Swift的编译时类型系统-或任何语言的静态类型检查。在某些情况下,您可以从逻辑上证明永远不会发生错误,但无法向编译器证明错误。因此,Swift的设计师首先添加了这些功能。

但是,无论何时使用 !,都排除了错误的恢复路径,这意味着……

2.感叹号是潜在的崩溃。

感叹号也说,“嘿斯威夫特,我这样一定能永远不会发生这个错误,它是更好地为您崩溃我的整个应用程序比它为我的代码为它复苏的道路。”

这是一个危险的主张。这可能是正确的:在关键任务代码中,您认真考虑过代码的不变量,这可能是伪输出比崩溃更糟糕。

但是,当我!在野外看到时,很少如此谨慎地使用它。取而代之的是,它常常表示:“此值是可选的,我对它为什么可能为零或如何正确处理这种情况并没有真正思考,但是添加了!使其编译即可...所以我的代码正确,对吗?”

当心惊叹号的傲慢。代替…

3.最好不要使用感叹号。

这些!构造中的每一个都有一个?对应项,迫使您处理错误/无用情况:

  • 有条件的展开: if let name = nameLabel?.text { ... }
  • 可选项目: var logo: UIImageView?
  • 有条件的强制转换: logo.image = thing as? UIImage
  • Nil-on-failure例外情况: try? NSJSONSerialization.JSONObjectWithData(data, [])

如果您想使用!,最好仔细考虑为什么不使用它?。如果!操作失败,使程序崩溃真的是最好的选择吗?为什么该值是可选的/失败的?

您的代码在nil / error情况下是否可以采用合理的恢复路径?如果是这样,请对其进行编码。

如果它不可能为nil,或者错误永远不会发生,那么有没有一种合理的方法来重做您的逻辑,以便编译器知道呢?如果是这样,请执行;您的代码将不那么容易出错。

有时候,没有合理的方法来处理错误,而仅仅忽略错误(从而处理错误的数据)比崩溃更糟那些时候使用武力解包。

我定期在我的整个代码库中搜索!并审核每次使用。很少有用法经得起审查。(在撰写本文时,整个Siesta框架只有两个 实例。)

这并不是说您永远不要!在代码中使用–只是您应该谨慎使用它,并且永远不要使其成为默认选项。


func isSubscriptionActive(receiptData: NSDictionary?) -> Bool { if(receiptData == nil) { return false; } return (hasValidTrial(receiptData!) || isNotExpired(receiptData!)) && isNotCancelled(receiptData!) } 给定3.有没有更好的编写方法?
jenson-button-event

您可以说func isSubscriptionActive(receiptData: NSDictionary?) -> Bool { guard let nonNilReceiptData = receiptData else { return false} return (hasValidTrial(nonNilReceiptData) || isNotExpired(nonNilReceiptData)) && isNotCancelled(nonNilReceiptData) }
rkgibson2

感叹号不会绕过任何安全检查。你得到了保证崩溃,如果选购为零。始终检查可选项。这只是进行安全检查的一种非常残酷的方法。
gnasher729

@ gnasher729答案指出,它规避了编译时安全检查,而支持安全的运行时故障。
保罗·坎特雷尔

24

john是可选的var。因此可以包含一个nil值。为确保该值不为零!,请在var名称末尾使用a 。

从文档

“一旦确定可选选项确实包含一个值,就可以通过在可选名称的末尾添加一个感叹号(!)来访问其基础值。感叹号有效地表示:“我知道此可选选项绝对有价值。请使用它。”

检查非零值的另一种方法是

    if let j = json {
        // do something with j
    }

1
是的,我已经在文档中看到了这一点,但是似乎仍然没有必要……因为对我而言,john.apartment = number73它还说:“我知道此可选内容绝对有价值;请使用它。” ...
Troy

6
是的,的确如此,但是重点是默认情况下,Swift会尝试在编译时捕获错误。如果您知道或认为您知道此变量不能包含nil,则可以使用感叹号删除该检查。
lassej 2014年

16

这里有些例子:

var name:String = "Hello World"
var word:String?

哪里word是可选值。表示它可能包含也可能不包含值。

word = name 

这里name有一个值,所以我们可以分配它

var cow:String = nil
var dog:String!

dog被强行拆开意味着它必须包含一个值

dog = cow

该应用程序将崩溃,因为我们被分配nil给未包装的


1
var c:Int = nil将会得到:“ Nil无法初始化指定的类型'int'”
Asususer

15

在这种情况下...

瓦尔·约翰:人!

这意味着,最初John将具有nil值,它将被设置,并且一旦设置就永远不会再被nil引导。因此,为了方便起见,我可以使用更简单的语法来访问可选的var,因为这是“隐式展开的可选”


1
谢谢。我还找到了以下链接对此进行了说明。这种类型称为“隐式展开选项”。stackoverflow.com/questions/24122601/...
Kaydell

5

如果您使用的是C族语言,那么您将想到“指向类型X的对象的指针,该对象可能是内存地址0(NULL)”,而如果您使用的是动态类型的语言,那么您将思考“可能是X类型但可能未定义类型的对象”。尽管第一个路口很近,但实际上都不是正确的。

您应该考虑的方式就好像它是一个像这样的对象:

struct Optional<T> {
   var isNil:Boolean
   var realObject:T
}

当您测试可选值时,foo == nil它实际上会返回foo.isNil,并且当您说foo!此可选值时会foo.realObject带有断言that foo.isNil == false。请务必注意这一点,因为如果foo您这样做时实际上为零foo!,则这是运行时错误,因此通常除非您非常确定该值不会为nil,否则通常要使用条件let。这种欺骗手段意味着可以对语言进行强类型化,而无需强迫您测试值是否在所有地方都为零。

实际上,它的行为并非如此,因为工作是由编译器完成的。从高层次上讲,有一个类型Foo?与分开Foo,并防止接受类型的Foo函数接收nil值,但在低层次上,可选值不是真正的对象,因为它没有属性或方法。实际上,这可能是一个指针,当强制展开时,可以通过适当的测试将其设为NULL(0)。

在其他情况下,您还会在类型上看到感叹号,例如:

func foo(bar: String!) {
    print(bar)
}

这大致相当于接受带有强制拆包的可选内容,即:

func foo(bar: String?) {
    print(bar!)
}

您可以使用此方法来从技术上接受一个可选值,但如果该方法为nil,则将出现运行时错误。在当前版本的Swift中,这显然绕过了is-not-nil断言,因此您将遇到一个低级错误。通常这不是一个好主意,但是在从另一种语言转换代码时可能很有用。



3

如果您熟悉C#,则就像Nullable类型一样,它们也使用问号声明:

Person? thisPerson;

在这种情况下,感叹号等效于访问可空类型的.Value属性,如下所示:

thisPerson.Value

2

在目标C中,没有值的变量等于'nil'(也可以使用与0和false相同的'nil'值),因此可以在条件语句中使用变量(值与'TRUE'相同的变量',而没有值的则等于'FALSE')。

Swift通过提供“可选值”来提供类型安全性。即它可以防止因分配不同类型的变量而形成的错误。

因此,在Swift中,条件语句只能提供布尔值。

var hw = "Hello World"

即使'hw'是一个字符串,也不能在目标C中的if语句中使用它。

//This is an error

if hw

 {..}

为此,需要将其创建为

var nhw : String? = "Hello World"

//This is correct

if nhw

 {..}

2

!在对象的末尾说该对象是可选的,如果可以返回nil,则将其解包。通常用于捕获可能导致程序崩溃的错误。


2

简而言之(!):声明变量并确定该变量持有值之后。

let assumedString: String! = "Some message..."
let implicitString: String = assumedString

否则,您将必须在每次传递值后执行此操作...

let possibleString: String? = "An optional string."
let forcedString: String = possibleString! // requires an exclamation mark

1

John是一个可选的Person,表示它可以保存一个值或为nil。

john.apartment = number73

如果john不是可选的,则使用。由于john永远不会为nil,因此我们可以确定不会以nil值调用apartment。而

john!.apartment = number73

向编译器保证john不为零,然后解开可选内容以获取john的值并访问john的apartment属性。如果您知道john不为零,请使用此选项。如果在nil可选参数上调用此函数,则会收到运行时错误。

该文档包括一个很好的示例,其中convertedNumber是可选的。

if convertedNumber {
    println("\(possibleNumber) has an integer value of \(convertedNumber!)")
} else {
    println("\(possibleNumber) could not be converted to an integer")
}

您是在说如果约翰为零,而我去了john.apartment = number73,除非我输入“!”,否则不会导致错误。在约翰之后?
Troy 2014年

如果john是可选的,则必须使用感叹号来访问其属性,因为编译器必须知道它不是nil。如果不是可选的,则不能使用感叹号。
康纳2014年

1
如果我必须对所有可选的var使用感叹号,那么Apple为什么还要烦恼它,而不是这样做,所以缺少感叹号意味着同一件事?似乎是不必要的膨胀...或者是否有可能不使用带有可选var的感叹号呢?
Troy

当您需要将可选参数设置为非零时,可以使用感叹号。就像在访问john属性的情况下一样。您可以执行var jack这样的操作:人员?= john,其中jack也是可选的或var jack:人员= john!杰克是人而不是零
Connor 2014年

是的,但是,在原始示例中,我取消引用john可选对象的事实不是告诉编译器我需要它为非nil吗?...在​​您的var jack: Person = john!示例中,是否不缺少??在Person告诉编译器您需要john不为零之后?总体而言,这!似乎有点多余...仍然感觉像我在!…… 的“为什么”部分丢失了某些东西……
Troy

1

简而言之,感叹号表示一个可选的内容已被解包。可选变量是可以具有值或没有值的变量-因此,您可以使用此处所示的if let语句检查变量是否为空,然后强制对其进行拆包。如果强行解开一个空的可选内容,则程序将崩溃,因此请小心!通过在对变量的显式赋值的末尾放置问号来声明可选项,例如,我可以这样写:

var optionalExample: String?

此变量没有值。如果我要解开该包,该程序将崩溃,并且Xcode会告诉您您尝试解开一个值为nil的可选包。

希望能有所帮助。



1

整个故事以一种称为“可选var”的快速功能开始。这些是可能具有值或可能没有值的变量。通常,swift不允许我们使用未初始化的变量,因为这可能导致崩溃或意外原因,并且还会为后门提供占位符。因此,为了声明一个初始值不确定的变量,我们使用“?”。声明了这样的变量后,要将其用作某些表达式的一部分,必须在使用前对其进行解包,解包是通过操作发现变量值的操作,该操作适用于对象。如果尝试使用它们而没有展开,则会出现编译时错误。要取消包装变量(可选变量),请使用感叹号“!” 用来。

现在有时您会知道这样的可选变量将由系统(例如)或您自己的程序分配值,但有时会在某些情况下(例如,UI插座)在这种情况下,而不是使用问号“?”声明可选变量。我们用 ”!”。

因此系统知道该变量以“!”声明 现在是可选的,没有任何价值,但将在其生命周期的稍后阶段收到一个价值。

因此,感叹号具有两种不同的用法:1.声明一个变量,该变量将是可选的,并且肯定会在以后接收值。2.在表达式中使用该可选变量之前,请先对其进行包装。

我希望上面的描述避免了太多的技术内容。


1

如果您将其用作可选项,则它将解开可选项并查看是否存在某些内容。如果在if-else语句中使用它,则为NOT的代码。例如,

if (myNumber != 3){
 // if myNumber is NOT 3 do whatever is inside these brackets.
)

1

可选变量可以包含值,也可以不包含值

情况1: var myVar:String? = "Something"

情况2: var myVar:String? = nil

现在,如果您询问myVar !,您将告诉编译器在情况1中返回一个值 "Something"

如果情况2,它将崩溃。

意思!标记将强制编译器返回一个值,即使该值不存在也是如此。多数民众赞成在为什么这名字叫力解开


@莫里兹 我不知道是这样吗?我不能回答是否已回答问题吗?我是什么问题或答案有问题吗?我不明白您为什么要正确回答它?我基于对概念的理解试图做出回答。我认为有些人会发现它对于清晰易懂的解释很有帮助。
Ashish Pisey

@Moritz现在这是建设性的。如果是这个原因,您应该首先告诉我这个更正。感谢您的反馈。我已经纠正了。
Ashish Pisey

0
Simple the Optional variable allows nil to be stored.

var str : String? = nil

str = "Data"

To convert Optional to the Specific DataType, We unwrap the variable using the keyword "!"

func get(message : String){
   return
}

get(message : str!)  // Unwapped to pass as String

1
请不要写没有添加以前答案未涵盖的内容的答案。
Dalija Prasnikar,2013年

-1

问你自己

  • 该类型person?是否具有apartment成员/属性?要么
  • 该类型person是否具有apartment成员/属性?

如果您无法回答此问题,请继续阅读:

要理解,您可能需要对泛型有超基本的了解。看这里。Swift中的很多东西都是使用泛型编写的。包括可选

这段斯坦福视频提供了以下代码。强烈建议您观看前5分钟

可选是仅包含2种情况的枚举

enum Optional<T>{
    case None
    case Some(T)
}

let x: String? = nil //actually means:

let x = Optional<String>.None

let x :String? = "hello" //actually means:

let x = Optional<String>.Some("hello")

var y = x! // actually means:

switch x {
case .Some(let value): y = value
case .None: // Raise an exception
}

可选绑定:

let x:String? = something
if let y = x {
    // do something with y
}
//Actually means:

switch x{
case .Some(let y): print)(y) // or whatever else you like using 
case .None: break
}

当您说出var john: Person?您的意思时,实际上是这样的:

enum Optional<Person>{
case .None
case .Some(Person)
}

上面的枚举是否有任何名为的属性apartment?在任何地方都可以看到吗?这存在一样!但是,如果您将其拆开即可以,person!则可以...它的功能是:Optional<Person>.Some(Person(name: "John Appleseed"))


如果您定义的var john: Person不是:var john: Person?那么您将不再需要!使用,因为Person它本身确实具有apartment


作为以后为什么!不建议使用解包的未来讨论,请参阅此问答


2
使用上面的实际幻灯片可能会侵犯版权:“……斯坦福大学确实保留了我们iTunes U收藏集中的所有内容的版权。” 网址http://itunes.stanford.edu。用您自己的话来说,回答您从该课程中学到的内容(可能会回答这个问题)可能更好(并且不要使用幻灯片,而是自然地以代码形式引用其中的相关部分,并附带参考)。
dfri

2
您的论点是自变量论。无论如何,我不认为斯坦福大学会来这里并行使DMCA权利,但如果您的回答是根据官方/有效来源以您自己的话说,而不是以上述方式直接复制这些来源的形式,那总会更好。特别是当我们谈论受版权保护的幻灯片时:再次,最好在代码块中引用幻灯片的内容(在这里SO的代码图像通常是禁止的!)。
dfri

1
我链接到的meta帖子仅描述了SO的解决方法:如果某个随机用户将其举报为侵犯版权,则此类帖子自然不会被删除:仅当例如Stanford代表时。将要来到这里,因为要删除的职位将需要执行。因此,我写了我不相信斯坦福会来这里并执行DMCA权利,...”。我在上面的观点是,我认为这可能是侵犯版权的行为(我认为这是错误的),但是自然没有人会强制执行。...
dfri

1
但是除此之外,出于多种原因,不建议张贴包含代码图像的问题或答案。总结一下:我试图通过这些注释来指出,由于两个主要原因(带有版权的幻灯片,代码图像),我认为当前形式的答案并不尽如人意。自然地,包括我自己在内的任何人都不会对此做任何事情,我只是将其指向我们以供将来参考(或者可能鼓励您改为通过代码块引用该帖子)。同意,iTunes U!:)
dfri

2
@dfri删除了图片
亲爱的,
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.