No idea why this doesnt work

xuanbao · · 492 次点击    
这是一个分享于 的资源,其中的信息可能已经有所发展或是发生改变。
<p>I&#39;m attempting to learn Go for the first time, im trying to make a blackjack game and its frustrating because i cant even get past the simple stuff.</p> <p>// Blackjack package main</p> <p>import ( &#34;fmt&#34;</p> <p>) type Scoreboard struct{ Name string Score int</p> <p>} func (s *Scoreboard) addingScore () (string,int) { Score += Score + Score return Name, Score }</p> <p>func main() { bob := &amp;Scoreboard{&#34;bob&#34;,10}<br/> //fmt.Println(bob)</p> <p>}</p> <p>Gives me an error saying that score and name are undeclared but i declared them in the struct?</p> <p>Also, are there no true OOP in go? I thought structs were &#34;classes&#34; similar to java but it just seems you can associate the field variables with a method and thats it.</p> <hr/>**评论:**<br/><br/>leeview: <pre><p>You have to prefix Score and Name with &#39;s.&#39; because Score &amp; Name are fields of s (type Scoreboard). Like here: <a href="http://play.golang.org/p/YagF7ocuxR">http://play.golang.org/p/YagF7ocuxR</a></p></pre>Prerogativ: <pre><p>Thank you wonderful people of reddit!! Another question, whats the differnce between </p> <p>func (s scoreboard) addingScore() (string, int) { blah blah }</p> <p>vs</p> <p>func (s *scoreboard) addingScore() (string, int) { blah blah }</p></pre>Marvelt: <pre><p>The first is a value (pass by value) and the second is a pointer (pass by reference).</p></pre>jwcrux: <pre><p>To expand on this, you would typically want to pass by reference when you are expecting to modify the caller (in this case &#34;s&#34;):</p> <p><a href="https://golang.org/doc/effective_go.html#pointers_vs_values" rel="nofollow">https://golang.org/doc/effective_go.html#pointers_vs_values</a></p></pre>DatFishDow: <pre><p>Look here: <a href="https://gobyexample.com/methods" rel="nofollow">https://gobyexample.com/methods</a></p></pre>beej71: <pre><p>The only thing you need to do here is explicitly use the receiver &#34;s&#34; when referring to the fields. It&#39;s analogous to saying &#34;this&#34;, but it&#39;s required in Go:</p> <pre><code>func (s *Scoreboard) addingScore() (string, int) { s.Score += s.Score + s.Score return s.Name, s.Score } </code></pre> <p>(Reddit note: adding 4 spaces before the code will format it properly.)</p> <blockquote> <p>Also, are there no true OOP in go? I thought structs were &#34;classes&#34; similar to java but it just seems you can associate the field variables with a method and thats it.</p> </blockquote> <p>It&#39;s OOP, but not in the Java sense. It&#39;s a little different. Here&#39;s some &#34;inheritance&#34;:</p> <pre><code>package main import &#34;fmt&#34; type animal struct { legCount int } type cat struct { animal lives int } func main() { c := cat{animal: animal{legCount: 4}, lives: 9} c.lives -= 2 // normal enough // Following two lines have the same effect: c.animal.legCount = 5 c.legCount = 5 // shorthand works, too fmt.Printf(&#34;%#v\n&#34;, c) // OUTPUT: main.cat{animal:main.animal{legCount:5}, lives:7} } </code></pre> <p>And look up Go&#39;s interfaces for ways to mix in functionality (as opposed to data), and ways to refer to a common &#34;base class&#34;. Here&#39;s an example that treats both &#34;cat&#34; and &#34;dog&#34; as a &#34;runner&#34;, so the runRunner() function can run them both without knowing their underlying types:</p> <pre><code>package main import &#34;fmt&#34; type cat struct { lives int } type dog struct { happinessLevel int } type runner interface { run() } func (c cat) run() { fmt.Println(&#34;Cat is running!&#34;) } func (d dog) run() { fmt.Println(&#34;Dog is running!&#34;) } func runRunner(r runner) { // ObLogansRunReference :) r.run() } func main() { c := cat{9} d := dog{3490} runRunner(c) // OUTPUT: Cat is running! runRunner(d) // OUTPUT: Dog is running! } </code></pre> <p>With the interface &#34;runner&#34;, any structs that implement the function &#34;run()&#34; automagically become &#34;runner&#34;s. So the runRunner() function only needs to know its argument satisfies the &#34;runner&#34; interface, nothing more.</p> <p>So it&#39;s a little different than you&#39;re used to in Java, but it&#39;s at least as expressive, IMHO.</p> <p>Have fun!</p></pre>izuriel: <pre><p>Your answer is not wrong but I think your wording is dangerous. There is no OOP in Go, you can apply certain concepts of OOP programming to Go but it&#39;s not supported by the language. The inheritance you speak of is not inheritance, it&#39;s embedding and has caveats that are not included with true inheritance. Saying they&#39;re the same is miseducation. Embedding more closely resembles Composition than Inheritance.</p> <p>It might be beneficial to keep this in mind in future. Also structs are not classes and strict methods are nothing more than syntactic sugar for more readable code segments. </p> <p>If you define a type Animal as such:</p> <pre><code>type Animal struct { LegCount int } </code></pre> <p>And then a type you want to &#34;subtype&#34; with animal called Cat:</p> <pre><code>type Cat struct { Animal Lives int } </code></pre> <p>You get exactly what you give. You have a type <code>Animal</code> with a single field, and you have a type <code>Cat</code> with two fields. You don&#39;t have a subclass of <code>Animal</code>. You have a <code>Cat</code> that <em>has an</em> <code>Animal</code> as part of it&#39;s structure. The act of embedding (field with no defined name) gives you some sugar that allows you to call &#34;methods&#34; from the type it&#39;s embedded in. So in this example (as was previously shown) you can call your <code>LegCount</code> value in two ways: <code>myCat.LegCount</code> or <code>myCat.Animal.LegCount</code>. You could not, however, pass your <code>Cat</code> into a method as an <code>Animal</code>. This works in OOP languages but not in Go:</p> <pre><code>func (a Animal) GetNoise() string { return &#34;&#34; } func (c Cat) GetNoise() string { return &#34;meow&#34; } func PrintAnimalSound(a Animal) { fmt.Println(a.GetNoise()) } </code></pre> <p>You can&#39;t call <code>PrintAnimalSound</code> with <code>myCat</code>, you have to pass in <code>myCat.Animal</code> which in turn prints nothing. As it&#39;s calling the method on <code>Animal</code>, not <code>Cat</code>. This is not inheritance.</p> <p>(<a href="http://play.golang.org/p/4F0uZzJ5CV" rel="nofollow">http://play.golang.org/p/4F0uZzJ5CV</a>)</p> <p>Instead, in Go, the way you would achieve this type of functionality is through the use of interfaces. If you defined Animal as an interface instead:</p> <pre><code>type Animal interface { LegCount() int GetNoise() string } </code></pre> <p>Then you can define a <code>Cat</code> like:</p> <pre><code>type Cat struct { Lives int } func (c Cat) LegCount() int { return 4 } func (c Cat) GetNoise() string { return &#34;meow&#34; } </code></pre> <p>And you could define a <code>Dog</code></p> <pre><code>type Dog struct {} func (d Dog) LegCount() { return 4 } func (d Dog) GetNoise() { return &#34;bark&#34; } </code></pre> <p>And suddenly our <code>PrintAnimalSound</code> works. In Go, interfaces are implicitly matched, so we never actually say that <code>Cat</code> implements <code>Animal</code> or that <code>Dog</code> does. We just define the methods <code>Animal</code> suggests and our type can be used as that interface. In this case, any type that defines a <code>LegCount() int</code> and <code>GetNoise() string</code> functions are considered an <code>Animal</code>.</p> <p>(<a href="http://play.golang.org/p/weKptwZpU4" rel="nofollow">http://play.golang.org/p/weKptwZpU4</a>)</p> <p>Long story short, in Go there is no inheritance - there is embedding. Embedding is a <em>has a</em> type relationship, not an <em>is a</em> type relationship. Using interfaces, and embedding you can emulate some common OO principles but not exactly and not as you&#39;re used to. </p> <p><strong>edit</strong> Spelling, and details</p></pre>joushou: <pre><p>Your answer is wrong <em>and</em> your wording is dangerous. Sorry, I had to do that.</p> <p>The object oriented programming paradigm does not require inheritance. The only thing required for the lange to support OOP is objects, which can be arbitrary data, and methods, which can be arbitrary routines or functions. Even C and assembly can be used as a full OOP environment, as OOP does not require that syntactic sugar ties methods to objects. A function taking a structure as first argument is therefore enough to have a &#34;method&#34; on an &#34;object&#34;, and it is in fact the way many languages implement OO.</p> <p>Inheritance is not a defining feature or requirement of OOP, and interfaces is often considered a superior form of polymorphism (&#34;implements over extends&#34;). Saying Go does not support OOP on that remark is like saying C++ does not support OOP because it does not have interfaces, but you can &#34;emulate it&#34;.</p> <p>TLDR; Go supports objects, methods and polymorphism (through interfaces), all with syntactic sugar and compiler support, and is fully OO by any definition of the term. Inheritance is not a defining aspect of the OO paradigm, and writing OO code in Go is natural.</p></pre>postman_: <pre><p>Do you mind providing sources backing up all of your claims?</p></pre>joushou: <pre><p>I can find you some sources, but I need to know what claims you are referring to. There&#39;s many papers on the subjects, but Wikipedia gives a decent intro to OO for the lazy.</p></pre>postman_: <pre><blockquote> <p>The object oriented programming paradigm does not require inheritance.</p> <p>The only thing required for the lange to support OOP is objects, which can be arbitrary data, and methods, which can be arbitrary routines or functions.</p> <p>A function taking a structure as first argument is therefore enough to have a &#34;method&#34; on an &#34;object&#34;</p> <p>Inheritance is not a defining feature or requirement of OOP, and interfaces is often considered a superior form of polymorphism (&#34;implements over extends&#34;).</p> <p>Go supports objects, methods and polymorphism (through interfaces), all with syntactic sugar and compiler support, and is fully OO by any definition of the term. Inheritance is not a defining aspect of the OO paradigm, and writing OO code in Go is natural.</p> </blockquote> <p>These ones, please.</p></pre>joushou: <pre><p>I asked to provide you with a better answer, but I see that you insist on being a smartass. Oh well.</p> <p>As for the requirements of OO, I present you with the dictionary entry:</p> <blockquote> <p>Object-oriented (of a programming language) using a methodology that enables a system to be modeled as a set of objects that can be controlled and manipulated in a modular manner. Also the very first paragraph on the wikipedia article: Object-oriented programming (OOP) is a programming paradigm based on the concept of &#34;objects&#34;, which are data structures that contain data, in the form of fields, often known as attributes; and code, in the form of procedures, often known as methods. A distinguishing feature of objects is that an object&#39;s procedures can access and often modify the data fields of the object with which they are associated (objects have a notion of &#34;this&#34; or &#34;self&#34;). In OO programming, computer programs are designed by making them out of objects that interact with one another.[1][2] There is significant diversity in object-oriented programming, but most popular languages are class-based, meaning that objects are instances of classes, which typically also determines their type. Many of the most widely used programming languages are multi-paradigm programming languages that support object-oriented programming to a greater or lesser degree, typically in combination with imperative, procedural programming. Significant object-oriented languages include Python, C++, Objective-C, Smalltalk, Delphi, Java, Swift, C#, Perl, Ruby and PHP.</p> </blockquote> <p>For better information on the subject, I suggest you find some talks, read some papers or go to a lecture on the subject. There is not official formal definition, but as such, there are also no formal official requirements. It&#39;s nothing but an abstract concept, and what most people consider &#34;OO&#34; is not in fact the idea of OO, but the common implementations they have worked with.</p> <p>As for &#34;Go supports objects, methods and polymorphism&#34; part, look at interfaces, structs and function receivers, which in OO parlance translates to interface inheritance, classes and methods.</p> <p>I don&#39;t mind helping you find information if you actually want it, but finding proper sources for this kind of information is a pain in the ass, and I&#39;m not going to bother if the work would not be appreciated.</p></pre>izuriel: <pre><p>I clearly say this:</p> <blockquote> <p>you can apply certain concepts of OO programming to Go</p> </blockquote> <p>Which is the case with just about any language. But being able to apply OO principles to a language does not make that language object oriented. C is not object oriented, it has no notion of objects. You can program in C and you can treat structs like objects thereby using C in an &#34;Object Oriented&#34; way, but that doesn&#39;t make C an OO language and neither does it with Go.</p> <p>I harp on inheritance primarily because it was the focus of the post I commented on.</p></pre>joushou: <pre><p>The language does not have to use the term &#34;object&#34; for it to be object oriented. Hell, in most languages that use the term &#34;object&#34;, it doesn&#39;t have anything to do with the &#34;oo&#34; idea of an instance. The main reason one would not consider C to be object oriented, is that there is no syntactic ties between a method (function taking a struct) and its object (the struct). An object is an instance of a type, the type often called a class, but for it to be OO, it must just be an arbitrary data type. An int is an object in any language that can make one. On most languages, the language itself does not refer to an instance as an &#34;object&#34;, with object often having a quite different meaning (Javascripts Object is a type describing a hashmap, for example).</p> <p>In C++, which I believe we all consider OO, in the most common case an object is technically a &#34;class instance&#34;, and in this case, &#34;class&#34; is not a magic OO thing, but in fact a struct, with the only differences involving default access level and some small differences regarding templates. While less common, a &#34;class instance&#34; and &#34;struct instance&#34; without templates and with fields access level explicitly defined (public/private) behave identically in C++.</p> <p>So, to get to my point - Why are methods on a struct instance OO in C++, but not OO in Go? Why is polymorphism OO in C++, but not OO in Go? The claim that Go is not an OO language makes no sense at all.</p></pre>postman_: <pre><p>You are wrong too, because you are talking about subtyping and not about inheritance.</p></pre>izuriel: <pre><p>Inheritance creates a subtype. If Cat extends Animal then Cat <em>is an</em> Animal. This relationship is such that from then on a Cat can be used anywhere an Animal can - which is, at it&#39;s core, what subtyping is about.</p></pre>postman_: <pre><p><a href="https://www.cs.utexas.edu/users/wcook/papers/InheritanceSubtyping90/CookPOPL90.pdf" rel="nofollow">https://www.cs.utexas.edu/users/wcook/papers/InheritanceSubtyping90/CookPOPL90.pdf</a></p></pre>joushou: <pre><p>Inheritance (implementation inheritance) and subtyping (interface inheritance) are two completely different concepts. Subtyping is about allowing you to create a type that can &#34;be&#34; a different type (an is-a relationship). Interfaces permit you to do this (interface inheritance, &#34;implements&#34; in Java). If you&#39;re confused about the wording, consider the interface as the supertype, your class as your subtype. </p> <p>Inheritance (that is, implementation inheritance, or &#34;extends&#34; in Java) is about inheriting functionality from a different type, and although this can be simulated to some extend with embedding (and yes, even to a useful extend), it does not exist in its full form in Go. </p></pre>beej71: <pre><blockquote> <p>There is no OOP in Go, you can apply certain concepts of OOP programming to Go but it&#39;s not supported by the language.</p> </blockquote> <p>I&#39;d disagree that there is no OOP in Go.</p> <p>If I might quote Donovan and Kernighan (who presumably were extensively peer-reviewed before publishing):</p> <p>&#34;[...] its approach to [...] object-oriented programming is unusually flexible.&#34;</p> <p>&#34;Composition is central to object-oriented programming in Go&#34;</p> <p>&#34;Since the early 1990s, object-oriented programming (OOP) has been the dominant programming paradigm in industry and education, and nearly all widely used languages developed since then have included support for it. Go is no exception.&#34;</p> <p>Chapter 6 of their book covers it in detail with many explicit mentions of OOP.</p> <p>But I do agree with you that it&#39;s radically different than Java.</p> <p>To the original poster, any time I use quotes around a term you should suspect that I&#39;m referring to something that doesn&#39;t exist in Go in the manner you&#39;re used to.</p> <blockquote> <p>Long story short, in Go there is no inheritance - there is embedding. Embedding is a has a type relationship, not an is a type relationship. Using interfaces, and embedding you can emulate some common OO principles but not exactly and not as you&#39;re used to. </p> </blockquote> <p>Absolutely agree.</p></pre>izuriel: <pre><p>It seems I may have been wrong about Go not being Object Oriented. Although Instill stand by that I can certainly see popular opinion is against me somInstep down from that argument. </p></pre>Prerogativ: <pre><p>Thank you!</p></pre>Prerogativ: <pre><p><a href="http://pastebin.com/UwwwGp84" rel="nofollow">http://pastebin.com/UwwwGp84</a> So i rewrote the program and i have a couple of issues. The first is i dont know how to remove a &#34;card&#34; from the array once i &#34;draw&#34; it (returned). I was under the assumption append is only for slices</p></pre>mc_hammerd: <pre><p>google go slice tricks wiki it has all the paradigms you need like delete join etc <code>cards = append(cards[:i], cards[i+1:])</code>where i is the index you drew or <code>cards=cards[1:]</code> if you drew the top card</p></pre>joushou: <pre><blockquote> <p><a href="http://pastebin.com/UwwwGp84" rel="nofollow">http://pastebin.com/UwwwGp84</a></p> </blockquote> <p>Your deck is a slice of Cards ([]Cards{}). Arrays are fixed length, and would be declared through [...]Cards{} (where the length is assumed from the literal), or [n]Cards{}, where the array becomes n long. Append only works on slices, as it may swap the underlying array, but since you have a slice, there is no issue.</p> <p>For slice tricks, as mc_hammerd mentions, see <a href="https://github.com/golang/go/wiki/SliceTricks" rel="nofollow">https://github.com/golang/go/wiki/SliceTricks</a>, but I also recommend giving <a href="https://blog.golang.org/slices" rel="nofollow">https://blog.golang.org/slices</a> a read to explain the concept of slices vs. arrays, and the mechanics of append.</p></pre>Prerogativ: <pre><p>Go is a bit frustrating haha. Before i go into deleting the &#34;top card&#34; in the deck i think i have several problems.</p> <p><a href="http://pastebin.com/NBnNZ5av" rel="nofollow">http://pastebin.com/NBnNZ5av</a></p> <p>The first is i modified the code to test whether or not the code in terms of the deck is doing what i want. I get two errors:</p> <pre><code>./Blackjack.go:72: syntax error: unexpected ) ./Blackjack.go:77: syntax error: unexpected } </code></pre> <p>Second of all, is this the right approach? I feel like with the way i created the deck it was faulty. Any advice on the approach?</p></pre>joushou: <pre><blockquote> <p><a href="http://pastebin.com/NBnNZ5av" rel="nofollow">http://pastebin.com/NBnNZ5av</a></p> </blockquote> <p>You&#39;re missing an ending curly bracket. Based on your indention, you think the the ending curly bracket on line 70 is ending your function, but in reality it is ending the slice literal, making Go confused when it reaches the next function declaration: &#34;A new function declaration?! But you didn&#39;t even finish your last one!&#34;. So, add a new line at line 70 and put &#34; }&#34; there.</p> <p>Also, your setDeck function has the return type set to slice of int, not slice of Cards, so that&#39;s going to be your next error.</p> <p>As for the &#34;right approach&#34;, it depends on what you want. Sure, it doesn&#39;t look too pretty, but it works - once you get more functionality down and a bit more experience, you might find a prettier way. You could, for example, have a global array of all potential cards, and copy it to a slice whenever you want a new deck, but you&#39;ll have to play around to find the prettiest solution, depending on your requirements.</p></pre>

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

492 次点击  
加入收藏 微博
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传